Repository navigation
Description
Audited on master at 5630d74ec9cd912d4e2f325349f1943cbc15bcc6. This is a scoped implementation item under #147, based on the typed control/dataflow/effect audit. Proposed syntax below is illustrative unless explicitly marked as a current reproducer.
Problem and current evidence
Normal compilation can succeed after replacing specified work with comments or placeholder values. nlsc/emitter.py:339–367 drops descriptive EDGE CASES; nlsc/emitter.py:371–447 emits comments/pass and non-throwing return placeholders; nlsc/emitter.py:524–568 substitutes defaults for type names; nlsc/emitter.py:622–629 substitutes None for unresolved output-producing prose. TypeScript has a corresponding undefined fallback in nlsc/emitter_typescript.py:288–302.
Current reproducer:
@module payment_probe
[checkout]
PURPOSE: Process a payment
LOGIC:
1. Process customer payment -> payment
RETURNS: payment
Parsing/shared validation succeeds; Python emits payment = None # TODO: Process customer payment and returns None. Separately, total = 42 followed by RETURNS: number returns an invented zero. Neither case establishes an executable implementation.
Implementation hints
- Introduce an explicit distinction between narrative content and executable statements. PURPOSE/descriptions remain free text; executable LOGIC and EDGE CASES must lower to recognized constructs or a declared operation.
- Add one shared lowering diagnostic with ANLU, exact source span, rejected text, and a hint such as using
[charge-payment](order) -> payment. Reuse the diagnostic catalog/JSON path from Full error UX: structured errors, --explain flag, recovery hints #148. - In the new strict semantic contract, reject unresolved executable content before emitting runnable artifacts or updating a successful lockfile. If legacy scaffolding remains necessary, make it an explicit scaffold/legacy mode and mark its output incomplete; it must not count as a verified executable.
- Do not guess that the last binding is the return value. Treat a declared result type and its implementation expression separately.
- Inventory the existing tests/examples that intentionally accept descriptive steps; provide migration guidance aligned with Formal language spec: define what .nl supports and what it doesn't #143/Versioning and compatibility guarantees for .nl spec #144. This changes a current compatibility behavior and must be deliberate.
- Guard prose rejection already exists from [Critical] Natural Language Guards Emit Verbatim as Invalid Python #121; extend the same principle across executable constructs.
Acceptance criteria
- The reproducer fails strict verify and compile with the same source-level diagnostic.
- Unresolved descriptive returns, output steps, conditional actions, and executable EDGE CASES cannot silently disappear.
- Explicit
none,void, zero, empty collections, and valid narrative descriptions still work. - Scaffold mode, if retained, is visibly incomplete and cannot be mistaken for successful strict validation.
- CLI run/watch/test use the same validation boundary; tests assert behavior/diagnostics rather than merely finding a variable name in output.
Implementation ordering
Can begin immediately; integrate with the checked IR work under #147.
Activity