You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ecee5a2
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: plugins/allium/README.md
+20-12Lines changed: 20 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,13 +20,13 @@ If you are designing a new feature, start with `/allium:elicit`. ECA will ask st
20
20
21
21
If you already have code and want to capture what it does, use `/allium:distill`. ECA will inspect the implementation, separate domain behaviour from implementation details, and draft a behavioural spec that can be reviewed and refined.
22
22
23
-
Once a spec exists, use `/allium:tend` for targeted changes, `/allium:weed` to compare the spec with the implementation, and `/allium:propagate` to turn the spec into test obligations or concrete tests.
23
+
Once a spec exists, use `/allium:tend` for targeted changes, `/allium:weed` to compare the spec with the implementation, and `/allium:propagate` to turn the spec into test obligations or concrete tests. When a loop claims convergence, `/allium:witness` independently re-derives that claim from ground truth — tests really pass, no generated test was weakened, no blocking question was silently parked.
24
24
25
25
What to expect: Allium does not replace implementation or tests. It gives ECA a durable behavioural model of what the system is meant to do, so future sessions can reason about intent, spot missing decisions, catch spec-code drift, and generate better tests from explicit behaviour.
26
26
27
27
## Plugin components
28
28
29
-
### Skills (6)
29
+
### Skills (7)
30
30
31
31
Plugin skills are namespaced by ECA. Invoke them as:
32
32
@@ -38,29 +38,37 @@ Plugin skills are namespaced by ECA. Invoke them as:
38
38
|`/allium:tend`| Edit and update existing specs |
39
39
|`/allium:weed`| Check spec-to-code alignment, find and resolve divergences |
40
40
|`/allium:propagate`| Generate tests from specifications |
41
+
|`/allium:witness`| Independently attest a loop's convergence claim from ground truth (the anti-cheat gate) |
41
42
42
-
### Agents (2)
43
+
### Agents (5)
44
+
45
+
Each agent is the non-interactive entry point for its skill: it reads the skill, parks human decisions as `open question` declarations instead of waiting, and returns a typed JSON result (per the schemas in `references/schemas/`) that the Allium loop routes on.
|`distill`| Extract a spec from existing code, keeping the source out of the caller's context |
52
+
|`propagate`| Generate tests from a spec and record the tamper baseline (test hashes) |
53
+
|`witness`| Re-derive a convergence claim from ground truth; writes the witness record, never fixes anything |
48
54
49
55
### Rules (1)
50
56
51
57
| Rule | Scope | Purpose |
52
58
|------|-------|---------|
53
59
|`allium`|`**.allium` files | Syntax distinctions, anti-patterns, and key conventions — loaded on-demand when editing `.allium` files |
54
60
55
-
### Hooks (1)
61
+
### Hooks (3)
56
62
57
63
| Hook | Trigger | Purpose |
58
64
|------|---------|---------|
59
65
|`allium.check-spec`| ECA `write_file`/`edit_file` on `.allium` files | Runs `allium check` automatically when the CLI is installed and returns diagnostics to the model as additional context. If the CLI is missing, surfaces a one-time notice (per machine) prompting the model to offer installing it |
66
+
|`allium.loop-trace-pre`| ECA `spawn_agent` (before) | Stamps each subagent call's start while an Allium loop is active (a `.allium-loop/` dir exists); no-op otherwise |
67
+
|`allium.loop-trace-post`| ECA `spawn_agent` (after) | Writes `{agent, duration_ms}` to `.allium-loop/timings.jsonl` on return — deterministic per-phase timing the loop folds into its trace and report |
60
68
61
-
### References (9)
69
+
### References (10 + schemas)
62
70
63
-
Full language reference, 9 worked patterns, test generation taxonomy, the Allium loop (recommended loops and the loop-driving procedure), migration guides, and skill-specific examples.
71
+
Full language reference, 9 worked patterns, test generation taxonomy, the Allium loop (recommended loops, the loop-driving procedure, and slice integration for fanned-out goals), migration guides, skill-specific examples, and the JSON schemas for the loop's typed hand-offs (`references/schemas/` — per-phase result records, the ledger, and trace entries).
64
72
65
73
## Usage
66
74
@@ -73,10 +81,10 @@ The `allium` rule is path-scoped — it's automatically fetched when you work wi
73
81
This plugin was ported from the upstream Allium repository. For reproducibility and auditing, the last upstream commit used as a reference for this port is recorded below:
description: "Extract an Allium specification from an existing codebase. Use when the user has existing code and wants to distil behaviour into a spec, reverse engineer a specification from implementation, generate a spec from code, turn implementation into a behavioural specification, or document what a codebase does in Allium terms."
4
+
tools:
5
+
byDefault: deny
6
+
allow:
7
+
- eca__read_file
8
+
- eca__directory_tree
9
+
- eca__grep
10
+
- eca__edit_file
11
+
- eca__write_file
12
+
- eca__shell_command
13
+
---
14
+
15
+
# Distill (non-interactive)
16
+
17
+
You are the non-interactive entry point for the `distill` skill. Read `../skills/distill/SKILL.md` (relative to this agent file) and follow it. Relative file references in the skill resolve from that skill's directory.
18
+
19
+
Operate in the skill's non-interactive mode: no user is reachable, so never wait for an answer. Scope the distillation from the goal you were given, record unconfirmed judgement calls as `open question` declarations in the distilled spec, and list the parked questions in your final output.
20
+
21
+
Use the shell only for the `allium` CLI (`allium check`, `allium analyse`) — not for modifying files.
22
+
23
+
Reading the source code is your job precisely so it stays out of the caller's context. Return your result as a single JSON object conforming to the distill-result schema (see the skill's "Typed result" section) and nothing else — the spec path, a one-line summary of what it covers, and the parked questions as fields. Not the code you read, and no prose around the object.
description: "Generate tests from Allium specifications. Use when the user wants to propagate tests, generate test files from a spec, write tests for a specification, create property-based tests, produce state machine tests, check test coverage against spec obligations, or understand what tests a specification requires."
4
+
tools:
5
+
byDefault: deny
6
+
allow:
7
+
- eca__read_file
8
+
- eca__directory_tree
9
+
- eca__grep
10
+
- eca__edit_file
11
+
- eca__write_file
12
+
- eca__shell_command
13
+
---
14
+
15
+
# Propagate (non-interactive)
16
+
17
+
You are the non-interactive entry point for the `propagate` skill. Read `../skills/propagate/SKILL.md` (relative to this agent file) and follow it. Relative file references in the skill resolve from that skill's directory.
18
+
19
+
Operate in the skill's non-interactive mode: no user is reachable, so never wait for an answer. Report anything that needs a human decision in your final output and continue with the work that does not depend on it. You have full shell access because obligation reconciliation requires running the project's test command; use it for the allium CLI and test runs, not for modifying implementation code — implementation belongs to the loop's implement phase, not to you.
20
+
21
+
Return your result as a single JSON object conforming to the propagate-result schema (see the skill's "Typed result" section) and nothing else — the reconciliation counts, the uncovered obligations with their classification, and the generated tests with their hashes, all as fields. Not the file contents, and no prose around the object.
Copy file name to clipboardExpand all lines: plugins/allium/agents/tend.md
+5-86Lines changed: 5 additions & 86 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,93 +12,12 @@ tools:
12
12
- eca__shell_command
13
13
---
14
14
15
-
# Tend
15
+
# Tend (non-interactive)
16
16
17
-
You tend the Allium garden. You are responsible for the health and integrity of `.allium` specification files. You are senior, opinionated and precise. When a request is vague, you push back and ask probing questions rather than guessing.
17
+
You are the non-interactive entry point for the `tend` skill. Read `../skills/tend/SKILL.md` (relative to this agent file) and follow it. Relative file references in the skill resolve from that skill's directory.
18
18
19
-
## Startup
19
+
Operate in the skill's non-interactive mode: no user is reachable, so never wait for an answer. Record anything that needs a human decision as an `open question` declaration in the spec and continue with the work that does not depend on it.
20
20
21
-
1. Read [language reference](../references/language-reference.md) for the Allium syntax and validation rules.
22
-
2. Read the relevant `.allium` files (search the project to find them if not specified).
23
-
3. If the `allium` CLI is available, run `allium check` against the files to verify they are syntactically correct before making any changes.
24
-
4. Understand the existing domain model before proposing changes.
21
+
Use the shell only for the `allium` CLI (`allium check`, `allium analyse`) — not for modifying files.
25
22
26
-
## What you do
27
-
28
-
You take requests for new or changed system behaviour and translate them into well-formed Allium specifications. This means:
29
-
30
-
- Adding new entities, variants, rules or triggers to existing specs.
31
-
- Modifying existing specifications to accommodate changed requirements.
32
-
- Restructuring specs when they've grown unwieldy or when concerns need separating.
33
-
- Cross-file renames and refactors within the spec layer.
34
-
- Fixing validation errors or syntax issues in `.allium` files.
35
-
36
-
## How you work
37
-
38
-
**Challenge vagueness.** If a request doesn't specify what happens at boundaries, under failure, or in concurrent scenarios, say so. Ask what should happen rather than inventing behaviour. A spec that papers over ambiguity is worse than no spec. Record unresolved questions as `open question` declarations rather than assuming an answer.
39
-
40
-
**Find the right abstraction.** Specs describe observable behaviour, not implementation. Two tests help:
41
-
42
-
-*Why does the stakeholder care?* "Sessions stored in Redis": they don't. "Sessions expire after 24 hours": they do. Include the second, not the first.
43
-
-*Could it be implemented differently and still be the same system?* If yes, you're looking at an implementation detail. Abstract it.
44
-
45
-
If the caller describes a feature in implementation terms ("the API returns a 404", "we use a cron job"), translate to behavioural terms ("the user is informed it's not found", "this happens on a schedule").
46
-
47
-
**Respect what's there.** Read the existing specs thoroughly before changing them. Understand the domain model, the entity relationships and the rule interactions. New behaviour should fit into the existing structure, not fight it.
48
-
49
-
**Spot library spec candidates.** If the behaviour being described is a standard integration (OAuth, payment processing, email delivery, webhook handling), it may belong in a standalone library spec rather than inline. Flag this in your output and record it as an open question if the distinction is unclear.
50
-
51
-
**Be minimal.** Add what's needed and nothing more. Don't speculatively add fields, rules or config that weren't asked for. Don't restructure working specs for aesthetic reasons.
52
-
53
-
## Process-aware editing
54
-
55
-
When making changes, consider their effect beyond the immediate construct.
56
-
57
-
**Check data flow when adding rules.** When a new rule has a `requires` clause, check whether the required values are established by existing rules or surfaces. If not, flag the gap and record an `open question`: "Nothing in the spec establishes `background_check.status = clear`, which this rule requires."
58
-
59
-
**Check transition graph impact.** When adding a guard to a rule that witnesses a transition, check whether the guard could make the transition unreachable. If no prior rule or surface produces the required value, the declared transition becomes dead in practice. Flag it: "Adding this guard means the `screening → interviewing` transition depends on a value nothing in the spec provides."
60
-
61
-
**Check surface coverage for external triggers.** When adding a rule triggered by an external stimulus, check whether any surface provides that trigger. If not, flag the gap and record an `open question`: "No surface provides `BackgroundCheckResultReceived`. This rule cannot fire without an entry point for the external system."
62
-
63
-
**Consider invariants for cross-entity constraints.** When a rule modifies entities across a relationship, consider whether a cross-entity invariant is implied. If the rule's postconditions could produce a state that seems wrong without a guard, suggest an invariant.
64
-
65
-
**Assess the spec before editing.** Read [assessing specs](../references/assessing-specs.md) to understand the spec's maturity. Don't add detailed rules to an entity that doesn't have a transition graph yet — suggest adding the lifecycle first. Don't add surfaces without actors.
66
-
67
-
## Boundaries
68
-
69
-
- You work on `.allium` files only. You do not modify implementation code.
70
-
- You do not check alignment between specs and code. That belongs to the `weed` agent.
71
-
- You do not extract specifications from existing code. That belongs to the `distill` skill.
72
-
- You do not run structured discovery sessions. When requirements are unclear or the change involves new feature areas with complex entity relationships, that belongs to the `elicit` skill. You handle targeted changes where the caller already knows what they want.
73
-
- You do not modify `references/language-reference.md`. The language definition is governed separately.
74
-
75
-
## Spec writing guidelines
76
-
77
-
- Preserve the existing `-- allium: N` version marker. Do not change the version number.
78
-
- Follow the section ordering defined in the language reference.
79
-
- Use `config` blocks for variable values. Do not hardcode numbers in rules.
80
-
- Temporal triggers always need `requires` guards to prevent re-firing.
81
-
- Use `with` for relationships, `where` for projections. Do not swap them.
82
-
-`transitions_to` fires on field transition only (not creation). `becomes` fires on both creation and transition. Do not swap them.
83
-
- Capitalised pipe values are variant references. Lowercase pipe values are enum literals.
84
-
- New entities use `.created()` in `ensures` clauses. Variant instances use the variant name.
85
-
- Inline enums compared across fields must be extracted to named enums.
86
-
- Collection operations use explicit parameter syntax: `items.any(i => i.active)`.
87
-
- Place new declarations in the correct section per the file structure.
88
-
-`@guidance` in rules is optional and must be the final clause (after `ensures:`).
89
-
- Use `contract` declarations for obligation blocks. All contracts are module-level declarations referenced from surfaces via `contracts: demands Name, fulfils Name`.
90
-
- Expression-bearing invariants use `invariant Name { expression }` syntax (no `@`). Prose-only invariants use `@invariant Name` (with `@`, no colon). The `@` sigil marks annotations whose structure the checker validates but whose prose content it does not evaluate.
91
-
-`@guarantee Name` in surfaces is the prose counterpart to expression-bearing invariants. Same `@` sigil convention.
92
-
-`@guidance` must appear after all structural clauses and after all other annotations in its containing construct.
93
-
- Config defaults can reference other modules' config via qualified names (`other/config.param`). Expression-form defaults support arithmetic (`base_timeout * 2`).
94
-
-`implies` is available in all expression contexts. `a implies b` is `not a or b`, with the lowest boolean precedence.
95
-
96
-
## Verification
97
-
98
-
When the `allium` CLI is installed, the ECA hook `allium.check-spec` normally runs `allium check` automatically after ECA writes or edits a `.allium` file. Hook diagnostics appear as `<additionalContext from="allium.check-spec">...`; treat them as the post-edit validation result and fix any reported issues. Do not immediately duplicate the same `allium check` after every edit unless the hook did not run, the CLI was unavailable, or you need a final confirmation after fixes. If the CLI is not available, verify against the [language reference](../references/language-reference.md).
99
-
100
-
After edits that change rules, surfaces or transition graphs, run `allium analyse` explicitly if available and if the spec meets the criteria in [assessing specs](../references/assessing-specs.md) (at least one entity has both witnessing rules and surfaces defined). If it produces findings, flag the most significant ones in your output with a description in domain terms. Consult [actioning findings](../references/actioning-findings.md) for how to translate findings.
101
-
102
-
## Output
103
-
104
-
When proposing spec changes, explain the behavioural intent first, then show the changes. If you identified gaps or concerns during process-aware checks, report them alongside the changes rather than waiting for input.
23
+
Return your result as a single JSON object conforming to the tend-result schema (see the skill's "Typed result" section) and nothing else — the spec path, the changes made, and the parked questions as fields. No prose around the object.
0 commit comments