Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Liminate is a prose-as-syntax programming language. The interpreter is a Python pipeline: lexer β†’ reorderer β†’ parser + renderer β†’ analyzer β†’ interpreter, with a Phase 2 event-driven listener layered on top.

Current vocabulary: 21 verbs, 22 connectives, 10 operators, 1 declaration, 60 reserved words. Domain packs may declare additional verbs and nouns via the pack-verb contract.
Current vocabulary: 21 verbs, 22 connectives, 10 operators, 2 declarations, 61 reserved words. Domain packs may declare additional verbs and nouns via the pack-verb contract.

## Critical Rules

Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Liminate is a prose-as-syntax programming language. The interpreter is a Python pipeline: lexer β†’ reorderer β†’ parser + renderer β†’ analyzer β†’ interpreter, with a Phase 2 event-driven listener layered on top.

Current vocabulary: 21 verbs, 22 connectives, 60 reserved words. Domain packs may declare additional verbs and nouns via the pack-verb contract.
Current vocabulary: 21 verbs, 22 connectives, 61 reserved words. Domain packs may declare additional verbs and nouns via the pack-verb contract.

## Critical Rules

Expand Down
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The sentence is the program.

*Part of the Prosecode family β€” a set of tools for writing, verifying, and transferring structured reasoning.*

Liminate is a prose-as-syntax language whose syntax is plain English. A small, bounded vocabulary of 60 reserved words combines into sentences that a real interpreter lexes, parses, type-checks, and runs. Not a prompt. Not a code generator. The prose IS the program.
Liminate is a prose-as-syntax language whose syntax is plain English. A small, bounded vocabulary of 61 reserved words combines into sentences that a real interpreter lexes, parses, type-checks, and runs. Not a prompt. Not a code generator. The prose IS the program.

## What it does

Expand Down Expand Up @@ -71,7 +71,7 @@ pytest tests/

## How it works

The current build is **v0.15.0**: 21 verbs, 22 connectives, 10 operators, 1 declaration, 60 base reserved words, **1499 tests passing**.
The current build is **v0.16.0**: 21 verbs, 22 connectives, 10 operators, 2 declarations, 61 base reserved words, **1654 tests passing**.

### The pipeline

Expand All @@ -82,27 +82,29 @@ Two phases of execution:
- **Phase 1 β€” sequential.** Each statement runs in order. Stepwise commit: if a later op fails, earlier side effects remain and the error names what was completed.
- **Phase 2 β€” reactive listener.** `when`/`unless` register handlers driven by an external event source (a domain pack adapter). Edge-triggered, depth-first cascading, conservative same-handler-twice cycle detection. `finish` exits immediately and totally.

### The vocabulary (60 words)
### The vocabulary (61 words)

**Verbs (21):** `remember`, `show`, `filter`, `keep`, `count`, `gather`, `sum`, `each`, `choose`, `finish`, `add`, `remove`, `weakens`, `require`, `forbid`, `permit`, `assign`, `expect`, `sort`, `compare`, `transform`. The Deontic Era completes the obligation/prohibition/permission triangle: `require` halts when its condition is false, `forbid` halts when its condition is true (`PROHIBITION_VIOLATED`), and `permit` emits an informational line when its condition is true but never halts. `sum` was renamed from `combine` in v0.15.0 β€” `combine` is tombstoned and now errors with a rename-specific message.
**Verbs (21):** `remember`, `show`, `filter`, `keep`, `count`, `gather`, `sum`, `each`, `choose`, `finish`, `add`, `remove`, `weakens`, `require`, `forbid`, `permit`, `assign`, `expect`, `sort`, `compare`, `transform`. The Deontic Era completes the obligation/prohibition/permission triangle: `require` halts when its condition is false, `forbid` halts when its condition is true (`PROHIBITION_VIOLATED`), and `permit` emits an informational line when its condition is true but never halts. `sum` was renamed from `combine` in v0.15.0 β€” `combine` is tombstoned and now errors with a rename-specific message. All four condition-bearing verbs in this family β€” `require`, `forbid`, `permit`, `expect` β€” additionally accept an `unless <exception>` clause after the main condition (v0.16.0): `forbid total is above 10000 unless approved is equal to yes`. Zero new words β€” `unless` in a new grammatical position.

**Connectives (22):** `where`, `and`, `or`, `from`, `with`, `called`, `to`, `how`, `as`, `of`, `if`, `otherwise`, `when`, `unless`, `includes`, `within`, `over`, `then`, `by`, `because`, `starting`, `until`. `because` attaches a quoted rationale to any verb statement as inert metadata β€” visible in canonical rendering, `inspect`, and Receipts, but never executed. Statement-terminal and per-statement: `require amount is above 50000 because "SOX compliance"`. The last two, `starting` and `until`, are statement-initial temporal modifiers that attach quoted ISO 8601 dates as inert metadata β€” an effective date and a sunset clause: `starting "2025-07-01" until "2025-12-31" require amount is above 50000`. Temporal evaluation is a product-layer concern, not interpreter runtime.

**Operators (10):** `is`, `above`, `below`, `not`, `plus`, `minus`, `reverse`, `inherited`, `highest`, `lowest`. Multi-word: `equal to`, `multiplied by`, `divided by`. `inherited` is a statement-initial modifier marking a verb statement as carried forward from a prior context (session, agent, contract) β€” inert provenance metadata, overridable, never executed. It reuses the `from` connective for statement-final agent attribution: `inherited require amount is above 50000 because "SOX compliance" from agent-compliance`. `highest`/`lowest` (v0.15.0) are list-extrema value selectors β€” `highest of nums` or `highest total of orders` β€” numeric-only, value-returning, and an error on an empty list.

**Articles (3):** `the`, `a`, `an` β€” decorative; the parser ignores them.

**Declarations (1):** `about` β€” declares the program's topic as inert metadata. Single, first-line-only; visible to tooling (`inspect`, the build manifest) but never stored or executed. `about "expense authorization"` or `about expense-authorization`.
**Declarations (2):** `about` and `define`. `about` declares the program's topic as inert metadata β€” single, first-line-only; visible to tooling (`inspect`, the build manifest) but never stored or executed: `about "expense authorization"` or `about expense-authorization`. `define <name>: <condition>` (v0.16.0's Definitional Era) names a reusable domain predicate β€” `define overdue: due-date is below cutoff` β€” referenced elsewhere as `is overdue` / `is not overdue`. Predicates compose, are redefinable, and work everywhere the condition grammar works (`where`, `require`, `forbid`, `when`, etc.) with no per-verb changes.

**Delimiter (1):** `:` β€” separates a composition name from its body, and a `choose` branch's condition from its action.

`"..."` brackets a multi-word string value or one that would collide with a reserved word. Quotes are value-position only; names use hyphens. Quoted content is preserved verbatim, case included.

Arithmetic expressions use PEMDAS precedence (multiply/divide before add/subtract, left-to-right within the same tier) and work in any value position.

Values include numbers, strings, dates, lists, and records. Dates (v0.16.0's Calendar Era) are bare ISO 8601 literals (`2025-07-01`, no quotes needed) with whole-day arithmetic (`2025-07-01 plus 30`), all comparison operators, day-based `within` tolerance, and `highest`/`lowest`/`sort` support.

### Domain packs

A pack is a small JSON file that adds nouns and verbs while it's loaded. The base 60 words are permanent; pack-contributed words are reserved only when the pack is active.
A pack is a small JSON file that adds nouns and verbs while it's loaded. The base 61 words are permanent; pack-contributed words are reserved only when the pack is active.

A pack verb declares a slot signature, a type constraint, and one of six execution dispatches:

Expand Down Expand Up @@ -161,7 +163,7 @@ The locked test sentences are simultaneously test cases and grammar artifacts
### Design principles

- **The prose IS the program.** No inference, no guessing. If the prose doesn't say it, it doesn't happen.
- **The vocabulary is the boundary.** 60 base reserved words. Expressiveness scales through composition and domain packs, not through adding keywords.
- **The vocabulary is the boundary.** 61 base reserved words. Expressiveness scales through composition and domain packs, not through adding keywords.
- **The reorderer does not guess.** Ambiguous arrangements produce an amber clarification prompt rather than a silent pick.
- **Authorize, don't author.** The on-ramp is modification of a working program, not authorship from a blank file.
- **The AST is the source of truth.** The parser reconstructs a canonical English sentence so you see what was understood before it runs.
Expand Down
Loading