docs: codify feature-acceptance criterion (LLM-author utility)
Adds DESIGN.md "Feature-acceptance criterion" as a top-level section: a feature ships only if (1) an LLM author naturally produces code that uses it, and (2) it measurably improves correctness or removes redundancy. Aesthetic appeal and human ergonomics do not count. Mirrored in CLAUDE.md as "Feature acceptance: LLM utility", paired with the existing "Design rationale != implementation effort". The two together narrow valid feature rationales to one thing: what the LLM author gets out of the feature. Trigger: the typeclass-design conversation around 22a. Rule was implicit in many past decisions (Decision 1's JSON-over-text choice, Decision 10's "what LLMs are good at" reasoning) but never stated as a feature-gate. Codifying it now means future feature proposals get evaluated against an articulated criterion instead of being re-derived each time. Documentation-only; no Rust, schema, or bench changes. Test state 288/0/3 unchanged.
This commit is contained in:
@@ -90,6 +90,19 @@ locality (modes belong to fn-parameter positions, not to types in
|
||||
general), and I retroactively had to add it. JOURNAL entries from
|
||||
2026-05-08 record the lesson.
|
||||
|
||||
### Feature acceptance: LLM utility
|
||||
|
||||
When deciding whether a proposed feature ships, the test is
|
||||
whether an LLM author naturally produces code that uses it AND
|
||||
whether the feature measurably improves correctness or removes
|
||||
redundancy. Aesthetic appeal does not count; neither does human
|
||||
ergonomics. The full criterion lives in DESIGN.md
|
||||
("Feature-acceptance criterion").
|
||||
|
||||
This is the positive complement to the rule above. Together they
|
||||
narrow the space of valid feature rationales to one thing: what
|
||||
AILang's actual user — the LLM author — gets out of it.
|
||||
|
||||
### Direction freedom
|
||||
|
||||
I have authority to choose the next iter, refactor, or feature
|
||||
|
||||
@@ -61,6 +61,48 @@ everything that lands in git is English. This keeps diffs and tooling output
|
||||
uniform and matches the audience for AILang (LLM authors), for whom English
|
||||
is the default.
|
||||
|
||||
## Feature-acceptance criterion
|
||||
|
||||
A proposed feature ships only if both hold:
|
||||
|
||||
1. **An LLM author naturally produces code that uses it.** Without
|
||||
prompting toward the feature, the LLM reaches for it as the clean
|
||||
way to express the situation. If the feature is only used when
|
||||
explicitly mentioned, it isn't earning its keep — the LLM is the
|
||||
only author, and what the LLM doesn't reach for naturally is dead
|
||||
surface area.
|
||||
|
||||
2. **The feature measurably improves correctness or removes
|
||||
redundancy.** Either it eliminates a class of bugs structurally
|
||||
(the schema forbids the wrong code), or it lets the LLM express the
|
||||
same logic in fewer sites that have to stay consistent across
|
||||
edits. Aesthetic appeal — "feels elegant", "is idiomatic" — does
|
||||
not count.
|
||||
|
||||
This is the positive complement to the CLAUDE.md rule that
|
||||
implementation effort is not a rationale: cost is not a reason *for* a
|
||||
feature, and neither is human aesthetic preference. The only thing
|
||||
that is, is LLM-author utility.
|
||||
|
||||
Two corollaries:
|
||||
|
||||
- **Human-attractive but LLM-neutral features are cut.** Point-free
|
||||
style, operator overloading, implicit conversions, syntactic
|
||||
shortcuts that hide structure. They reward human authors who enjoy
|
||||
compression; they cost the LLM the explicit form it relies on to
|
||||
keep RC, uniqueness, and effects locally legible.
|
||||
|
||||
- **Human-hostile but LLM-friendly features are kept.** JSON as
|
||||
canonical authoring surface; mandatory mode annotations on every
|
||||
fn parameter; mandatory top-level type signatures; explicit `clone`
|
||||
for shared values. These cost a human author keystrokes; they let
|
||||
the LLM reason locally without spending context window on
|
||||
cross-references.
|
||||
|
||||
Empirically: if a feature is proposed and the LLM does not produce it
|
||||
in unprompted code samples, the feature is proposed for the wrong
|
||||
reason. The orchestrator's job is to notice that and cut.
|
||||
|
||||
## Decision 1: source = data, not text
|
||||
|
||||
A module is a JSON object with a fixed schema. There is no parser for
|
||||
|
||||
@@ -10782,3 +10782,86 @@ All three bench scripts re-run sequentially after edits:
|
||||
- **Family 21+** — typeclasses, polymorphic ADTs at runtime,
|
||||
pattern-binding generalisation. Orchestrator-level fork; needs
|
||||
direct user input before dispatch.
|
||||
|
||||
## 2026-05-09 — Feature-acceptance criterion codified
|
||||
|
||||
Trigger: the typeclass-design conversation around 22a surfaced a
|
||||
recurring meta-question — when is a proposed feature actually
|
||||
worth shipping. The negative form was already in CLAUDE.md
|
||||
("Design rationale ≠ implementation effort": cost is not a
|
||||
reason for a feature). The positive form was implicit in many
|
||||
decisions (Decision 10's reasoning explicitly invokes "what
|
||||
LLMs are good at vs. not"; the JSON-over-text choice in
|
||||
Decision 1 is justified by LLM-readability) but never stated as
|
||||
a feature-acceptance gate.
|
||||
|
||||
This entry codifies it. New top-level section in DESIGN.md
|
||||
("Feature-acceptance criterion"): a feature ships only if (1)
|
||||
an LLM author naturally produces code that uses it without
|
||||
prompting toward it, AND (2) the feature measurably improves
|
||||
correctness or removes redundancy. Aesthetic appeal — "feels
|
||||
elegant", "is idiomatic" — does not count; neither does human
|
||||
ergonomics. Two corollaries: human-attractive but LLM-neutral
|
||||
features (point-free style, operator overloading, implicit
|
||||
conversions) are cut; human-hostile but LLM-friendly features
|
||||
(JSON authoring surface, mandatory mode annotations, mandatory
|
||||
top-level signatures) are kept.
|
||||
|
||||
Mirrored briefly in CLAUDE.md as a sub-section
|
||||
"Feature acceptance: LLM utility", paired with the existing
|
||||
"Design rationale ≠ implementation effort". The two together
|
||||
fully narrow the space of valid feature rationales: not cost,
|
||||
not aesthetics, only LLM-author utility.
|
||||
|
||||
### Why now
|
||||
|
||||
The typeclass conversation was the surfacing event. When asked
|
||||
to construct two examples that pure monomorphisation cannot
|
||||
handle (heterogeneous Show-able container; higher-rank
|
||||
polymorphism), the natural response was: both are features that
|
||||
an LLM author would not unprompted produce. Heterogeneous
|
||||
containers reduce to closed-world sum types in practice;
|
||||
higher-rank polymorphism reduces to two separate functions.
|
||||
Without the rule explicitly named, the next instance of "should
|
||||
we add feature X" would replay the same reasoning from scratch.
|
||||
Codifying it now means future feature proposals get gated by an
|
||||
articulated criterion, not by re-derivation.
|
||||
|
||||
### Implications for 22a (next iter)
|
||||
|
||||
The rule is the explicit basis for the typeclass-design choices
|
||||
that 22a will make:
|
||||
|
||||
- **Monomorphisation as default dispatch strategy.** A pure-mono
|
||||
language with rank-1-only polymorphism is exactly what a
|
||||
natural LLM author produces. Dictionaries would handle features
|
||||
(heterogeneous containers, higher-rank) that are real but not
|
||||
LLM-natural — so they don't ship.
|
||||
- **Higher-rank polymorphism rejected at parse time.** Error
|
||||
message proposes the canonical workaround (two separate
|
||||
functions). LLM-friendly: clear cut over subtle codegen
|
||||
fallback.
|
||||
- **Heterogeneous containers via sum types, not `dyn Show`.**
|
||||
Same reasoning. Sum types are what the LLM would produce
|
||||
unprompted; type-erased existentials are not.
|
||||
|
||||
If the rule were inverted — "ship every feature a sufficiently
|
||||
sophisticated user might want" — 22a would commit to dictionary
|
||||
passing and existential types from day one, and AILang would
|
||||
gain the same dispatch overhead and codegen complexity that
|
||||
make general-purpose languages opaque to the optimizer. The
|
||||
rule cuts that off.
|
||||
|
||||
### Test state
|
||||
|
||||
288 / 0 / 3, unchanged. Documentation-only commit; no Rust,
|
||||
schema, or bench changes.
|
||||
|
||||
### JOURNAL queue
|
||||
|
||||
Unchanged from 21'g. Next dispatch is 22a (typeclass design
|
||||
iter), which is orchestrator-level work the orchestrator does
|
||||
directly: DESIGN.md typeclass section, instantiation strategy,
|
||||
schema nodes for `class` and `instance`, naming convention for
|
||||
monomorphised functions. Implementer iter (22b) follows after
|
||||
22a's design lands and is reviewed.
|
||||
|
||||
Reference in New Issue
Block a user