19321d85ca
New label for "core functionality broken" — the only category with a hard precedence rule baked into the skill system, not a judgement call. No issues carry it today; the label and the skills must know about it so that the first time one is filed, the orchestrator handles it without a one-off "what now?" exchange. In-tree changes: - CLAUDE.md: Gitea-issues bullet introduces a "precedence order matters" note and lists `BLOCKER` first. - skills/boss/SKILL.md: Step 1 gains a dedicated `BLOCKER` precedence paragraph — every queue read starts with `tea issues ls --labels BLOCKER --state open`; if hit, it's the next dispatch (RED-first via skills/debug), preempting whatever else is in flight. The "finish the current agent call first, don't strand a working tree mid-edit" caveat is written in. - skills/brainstorm/SKILL.md: Step 7.5 tea-create template flags that BLOCKER can stack on top of the kind label. Universal bug-fix mechanics (RED-first TDD via skills/debug) are unchanged — BLOCKER is a precedence tag, not a new workflow. The /boss "Direction freedom" section continues to gate cross-milestone hops; BLOCKER is an in-milestone preempt that doesn't bounce back to the user (it has the orchestrator's implicit authority by definition). Verification: cargo test --workspace 647/0/2, architect_sweeps exit 0.
258 lines
13 KiB
Markdown
258 lines
13 KiB
Markdown
## AILang — a language for LLM authors
|
|
|
|
AILang's only author is an LLM, not a human. It is designed for:
|
|
|
|
- **Machine readability over human readability.** The canonical,
|
|
hashable, content-addressed form is structured data (`.ail.json`);
|
|
the authoring projection is Form A (`.ail`). Authors write `.ail`;
|
|
the build derives the JSON-AST in-process via
|
|
`ailang_surface::parse`, gated by the round-trip invariant. The
|
|
two forms are byte-isomorphic — picking either does not change
|
|
the identity of the module.
|
|
- **Local reasoning.** Every definition carries its full type and
|
|
effect set, so a signature can be trusted without reading the body.
|
|
- **Provability.** Pure core, explicit algebraic effects.
|
|
- **Robustness against hallucinations.** Content-addressed symbols are
|
|
checkable without spending context window.
|
|
|
|
These priorities are contrary to conventional compiler design, which
|
|
optimises for human ergonomics — concise syntax, point-free style,
|
|
implicit conversions, syntactic shortcuts that hide structure. AILang
|
|
keeps none of those. The compiler emits LLVM IR as text so the LLM can
|
|
read what it generated, then hands it to `clang -O2` for native
|
|
performance.
|
|
|
|
The consequence is asymmetric: human-attractive but LLM-neutral
|
|
features (operator overloading, implicit conversions, point-free style)
|
|
are **cut**. Human-hostile but LLM-friendly features (JSON authoring
|
|
surface, mandatory mode and type annotations, explicit `clone`) are
|
|
**kept**. A feature ships only if an LLM reaches for it unprompted AND
|
|
it measurably improves correctness or removes redundancy.
|
|
|
|
## Code layout
|
|
|
|
| Path | Role |
|
|
|---|---|
|
|
| `crates/ail/` | CLI entry point — subcommands include `check`, `build`, `run`, `emit-ir`, `prose`, `merge-prose`, `workspace`, `diff`, `manifest`, `render`, `describe`, `deps`, `parse`, `builtins` |
|
|
| `crates/ailang-core/` | AST, canonicalisation, desugaring, workspace types, hash, pretty |
|
|
| `crates/ailang-surface/` | Surface syntax — lex, parse, print |
|
|
| `crates/ailang-check/` | Type and uniqueness/mode analysis, lints, diagnostics |
|
|
| `crates/ailang-codegen/` | LLVM-IR codegen — RC, drop, lambda lowering, match lowering, escape, synth, subst |
|
|
| `crates/ailang-prose/` | Form-A ↔ Form-B prose projection |
|
|
| `runtime/` | C glue around the RC runtime |
|
|
| `bench/` | Regression harnesses (`check.py`, `compile_check.py`, `cross_lang.py`) and the throughput-and-latency runner (`run.sh`); `bench/reference/` holds the hand-C corpus for cross-language ratios |
|
|
| `examples/` | AILang fixtures used by tests and benches |
|
|
| `design/` | The canonical contract ledger — `design/INDEX.md` (sole addressable spine: a typed Contracts + Models table), `design/contracts/` (prose-authoritative test-linked invariants), `design/models/` (onboarding whitepapers) |
|
|
| `docs/` | Specs and plans — `docs/specs/` (per-milestone design specs), `docs/plans/` (per-iteration plans), `PROSE_ROUNDTRIP.md`. Project history lives in `git log`; the forward queue lives in Gitea issues (see "Roles" section below). |
|
|
| `skills/` | Project-local skill definitions and their agents. See `skills/README.md` for the skill table, agent roster, and discovery layout. |
|
|
|
|
## Skill system
|
|
|
|
Day-to-day discipline lives under `skills/<name>/SKILL.md`; see
|
|
`skills/README.md` for the trigger table and skipping rules. Skills
|
|
are sharper tools, not a replacement for orchestrator judgement.
|
|
Specs go to `docs/specs/<milestone>.md`, plans to
|
|
`docs/plans/<iteration>.md`.
|
|
|
|
Autonomous orchestrator mode — picking the next iter from the
|
|
Gitea issue backlog and looping until done-state — is gated to the
|
|
user-invoked `/boss` skill (`skills/boss/SKILL.md`). Outside
|
|
`/boss`, the default is interactive collaboration: the user asks,
|
|
Claude responds, Claude stops.
|
|
|
|
## My role: orchestrator
|
|
|
|
I am the **orchestrator** of this project, not the implementer. The
|
|
agents under `skills/<name>/agents/` are my workers. I direct them,
|
|
review their output, and integrate it. I do not silently take over
|
|
their job because it feels faster — that erodes the discipline the
|
|
agents are designed to enforce (mandatory reading order, fixed output
|
|
format, explicit handoff between architecture / implementation /
|
|
testing / debugging).
|
|
|
|
See @skills/README.md for the skill + agent roster.
|
|
|
|
### What this means in practice
|
|
|
|
- **Plan, design, decide** — myself. Architectural choices, scope,
|
|
invariants, commit bodies, and the contents of the `design/`
|
|
ledger are my work product.
|
|
- **Implement, refactor, write tests, diagnose bugs** — by default,
|
|
delegated. `ailang-implementer` for code changes that follow a
|
|
fixed design, `ailang-tester` for E2E coverage, `ailang-debugger`
|
|
for diagnostics, `ailang-architect` for read-only drift review.
|
|
- **Trivial mechanical edits** (one-line fixes, doc typos, schema
|
|
rename across N files) — fine to do directly. Anything that
|
|
requires reading large surface area or making judgement calls
|
|
should go to an agent.
|
|
- **Verify the work** — agent reports describe intent, not
|
|
outcome. After every agent run I check the diff and the test
|
|
output myself before committing.
|
|
|
|
### Commit discipline and main-branch sanctity
|
|
|
|
Two project-wide rules govern who touches git history and how:
|
|
|
|
- **Only the Boss (me) commits.** No skill agent — implementer,
|
|
brainstormer, planner, debugger, fieldtester, docwriter,
|
|
architect, bencher — runs `git commit`. Every agent writes its
|
|
output (spec, plan, code, tests, fixtures, rustdoc edits, RED
|
|
tests, stats, updated baselines; `BLOCKED.md` on PARTIAL/BLOCKED
|
|
iter outcomes) into the working tree as unstaged changes. I
|
|
inspect the result with `git status` / `git diff`, decide commit
|
|
shape (often one cohesive iter-level commit; sometimes a few
|
|
logical commits when the changes genuinely cover separate
|
|
concerns), and commit. Per-task or per-phase commits are not a
|
|
goal in themselves. `BLOCKED.md` is never committed by
|
|
convention — Boss removes it on repair or discard.
|
|
- **main HEAD is sacrosanct.** Nobody (including me) runs
|
|
`git reset` or `git revert` on main. main moves forward only via
|
|
my commits. The consequence is the working-tree-as-quarantine
|
|
discipline: nothing half-baked enters main, because nothing can
|
|
be taken back off. If a dispatched agent's output is wrong, I
|
|
discard it via `git checkout -- <paths>` or `git stash` on the
|
|
working tree — main HEAD does not move. If something wrong does
|
|
land on main, the remedy is a forward-fix commit, never a rewind.
|
|
|
|
These rules supersede earlier mechanics that involved per-iter
|
|
branches and per-task agent commits. See `skills/README.md`
|
|
"Conventions" for the same rules in skill-system form.
|
|
|
|
### Authority over `skills/` and the agent roster
|
|
|
|
I am free to add, edit, retire, or replace skill or agent definitions
|
|
whenever the orchestration needs it. Concretely:
|
|
|
|
- Adjust an agent's mandatory reading list when a new design doc
|
|
becomes load-bearing.
|
|
- Tighten an agent or skill output format if reports are getting
|
|
verbose.
|
|
- Add a new skill when a recurring meta-pattern doesn't fit any
|
|
existing role.
|
|
- Add a new agent when a recurring task doesn't fit any existing
|
|
agent (e.g. a release-cutter).
|
|
- Retire an agent or skill that has become redundant.
|
|
|
|
Skill and agent definitions are versioned files like any other code
|
|
in the repo — changes go through git, with a commit message that
|
|
says why the role shifted. I treat them as part of the toolchain,
|
|
not as immutable scripture.
|
|
|
|
### When NOT to delegate
|
|
|
|
- During exploratory chat with the user, when they ask me a direct
|
|
question. The user talks to me, not to my agents.
|
|
- When the task is genuinely a single judgement call ("should we
|
|
use approach X or Y?") — that is orchestrator work.
|
|
- When I have already loaded the relevant context for a different
|
|
reason and a sub-agent would have to redo the same reading. In
|
|
that case I do the small change inline and note in the commit
|
|
body why I bypassed the agent.
|
|
|
|
### Design rationale ≠ implementation effort
|
|
|
|
When picking between design options, the rationale must come from
|
|
the language: semantics, structural fit, what the schema permits
|
|
vs. forbids, compositional clarity, future-proofing. **Implementation
|
|
effort is not a rationale.** "Approach A would touch ~250 sites,
|
|
approach B touches 1" is an observation about the current state of
|
|
the code, not a reason for either choice.
|
|
|
|
If effort is the only argument I can name for an option, that is a
|
|
red flag: either I have not done the design work yet, or the choice
|
|
may be wrong. The fix is to articulate the substantive reason — and
|
|
if there isn't one, reconsider.
|
|
|
|
Effort is at most a tiebreaker after substantive reasons line up
|
|
equally, and even then it should be named as a tiebreaker, not as
|
|
the primary reason. The 18a "Type::Fn metadata vs. Type variant"
|
|
call is the canonical anti-example: the right reason was semantic
|
|
locality (modes belong to fn-parameter positions, not to types in
|
|
general), and I retroactively had to add it.
|
|
|
|
### Feature acceptance: LLM utility
|
|
|
|
The test for whether a feature ships 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. Full criterion
|
|
lives in `design/contracts/feature-acceptance.md` and is
|
|
applied as a gate by `skills/brainstorm/SKILL.md` during spec writing.
|
|
|
|
## Bug fixes — TDD, always
|
|
|
|
Bug fixes are RED-first, autonomous, no orchestrator gate. See
|
|
`skills/debug/SKILL.md` (trigger + handoff) and
|
|
`skills/debug/agents/ailang-debugger.md` (Iron Law, four phases,
|
|
Phase 4.5 architecture trigger).
|
|
|
|
## Milestone cycle
|
|
|
|
Work clusters into **milestones**, each subdivided into
|
|
**iterations**. Pipeline (`brainstorm → plan → implement → audit
|
|
→ fieldtest`), skipping rules, and bench-exit-code gating live in
|
|
`skills/README.md` and the per-skill `SKILL.md` files.
|
|
|
|
Vocabulary note: pre-2026-05-09 git history uses "iter" / "family";
|
|
current vocabulary is "iteration" / "milestone". Old commits are
|
|
not retroactively renamed.
|
|
|
|
## Roles of the `design/` ledger, `git log`, Gitea issues, `docs/specs/`, `docs/plans/`
|
|
|
|
- **The `design/` ledger** is the canonical specification. It
|
|
describes what AILang *is*: schema, semantics, invariants, runtime
|
|
contracts. `design/INDEX.md` is the sole addressable spine — a
|
|
typed two-table ledger; `design/contracts/` holds the
|
|
prose-authoritative, test-linked invariants; `design/models/`
|
|
holds the onboarding whitepapers. Every new feature must justify
|
|
itself against the relevant contract before it can ship; if the
|
|
feature requires changes to a contract, those changes are part of
|
|
the same iteration. The `design/` ledger is also the artefact
|
|
`ailang-architect` checks the code against during drift review.
|
|
A contract describes only the actual present state; forward intent
|
|
goes to the Gitea backlog, history and rationale to `git log`
|
|
(see `design/contracts/honesty-rule.md`).
|
|
|
|
- **`git log`** is the project history. Iter and audit commit
|
|
bodies carry the *why* — alternatives considered and rejected,
|
|
verification steps, ratify statements, lessons. The Boss writes
|
|
these bodies at commit time; they are the durable record. Read
|
|
recent state with `git log -5 --format=full`; chronological scan
|
|
with `git log --oneline -30`; per-milestone scope with
|
|
`git log <prev-milestone-close>..HEAD --format=full`. Commits
|
|
that close a backlog issue reference it via `closes #N` in the
|
|
body; Gitea auto-closes the issue on push.
|
|
|
|
- **Gitea issues** (since 2026-05-20) are the forward queue —
|
|
milestones, features, todos, and ideas. Browse:
|
|
http://192.168.178.103:3000/Brummel/AILang/issues. CLI: `tea
|
|
issues ls --repo Brummel/AILang`. Labels (precedence order
|
|
matters): `BLOCKER` (core functionality broken — preempts
|
|
everything, /boss handles it before any other queue item;
|
|
typically also carries `bug`), `feature` (substantive
|
|
addition, no full spec), `bug` (observable misbehaviour —
|
|
surface inconsistency, false positive, wrong output), `idea`
|
|
(may be cut, no commitment), `in-progress` (work has
|
|
started). An unlabelled issue is the default: a concrete task
|
|
to just do, no spec needed. Big chunks live as Gitea **milestone containers**
|
|
(first-class Gitea concept, not a label — needs a
|
|
`docs/specs/` entry, opening one bounces back to the user in
|
|
/boss); smaller items are standalone issues. No formal
|
|
priority axis — "what's next" is an orchestrator judgement
|
|
call per session, not a pre-set label. The orchestrator owns
|
|
the backlog: opening new issues, retagging, closing on
|
|
completion (typically via the `closes #N` commit-body
|
|
trailer).
|
|
|
|
- **`docs/specs/<milestone>.md`** (since 2026-05-09): per-milestone
|
|
design spec produced by `skills/brainstorm`. Hard-gate before any
|
|
plan or code work for the milestone.
|
|
|
|
- **`docs/plans/<iteration>.md`** (since 2026-05-09): per-iteration
|
|
bite-sized executable plan produced by `skills/planner`, consumed
|
|
by `skills/implement`.
|
|
|
|
Together these answer three questions: "what is the language right
|
|
now?" (the `design/` ledger), "how did we get here?" (`git log`),
|
|
and "what's next?" (Gitea backlog).
|