Chorus
view release on metacpan or search on metacpan
agent/skills/chorus-feed.md view on Meta::CPAN
> FIND:
> p:
> attribut: needs_check
> ACTION: |
> my @pending = grep { !defined $_->{status} }
> Chorus::Frame::fmatch(slot => 'needs_check');
> if (@pending == 0) { $SELF->solved(); return 1 }
> 0
> ```
>
> **Solution**: global termination rule â **pure Perl `addrule()`** in the shell Agent,
> with `$agent` captured in a closure (see `chorus-check.md`, Phase 3, termination rule).
> Never code a termination via global `fmatch` in a YAML.
**When to document `PREMISES`:**
Always document if the agent is likely to use `reorder()` to
optimize rule order at runtime. PREMISES declare
the slots the rule needs â the sorting code consults them via `$rule->_PREMISSES`.
YAML Checklist:
- [ ] â **`type_element` â canonical name enforced:** the slot identifying the element type
is always named `type_element` in YAML (`attribut: type_element`), the KB Slot dictionary,
and the project JSON. Never `element_type`, `type`, `kind`, or any variant.
A mismatch silently produces 0 processed frames (SOLVED but all unprocessed).
- [ ] **Header present** â every `.yml` file opens with the structured `##` header (RULE/REGLE, AGENT, CORPUS, PURPOSE/OBJECTIF, INPUTS/ENTRÃES, OUTPUTS/SORTIES, HELPERS, GUARD). Header language matches the corpus language.
- [ ] **CORPUS line filled** â references the exact §N article from the corpus. If not identifiable â `# CORPUS: TODO â source not identified`.
- [ ] **ACTION/EFFET body commented** â each logical block has a one-line comment; early `return 0` statements explain why the Frame is skipped.
- [ ] Slot names = Slot dictionary from the KB
- [ ] **`CHERCHER`/`FIND` has a named scope variable** â the scope key must be a variable name (`f:`, `e:`, `p:` â¦), not directly `attribut:`. Without it the engine treats `attribut` itself as the variable name â runtime crash.
```yaml
# â WRONG â no scope variable; engine crashes at rule compilation
CHERCHER:
attribut: type_element
filtre: "defined $_->{type_element}"
# â
CORRECT
CHERCHER:
f:
attribut: type_element
filtre: "defined $_->{type_element}"
```
- [ ] **`filtre` uses `$_`, not `$f`** â see `chorus-engine-yaml.md` checklist.
- [ ] **`CONDITION` tests data presence, not conformance** â see `chorus-engine-yaml.md` checklist.
- [ ] Every rule that sets a slot has its idempotence `EXCEPTION: defined $var->{slot_set}`
- [ ] `ACTION` ends with `1` or a truthy expression
- [ ] â **`$f->{slot} = val` in ACTION** â silent pipeline break (`fmatch` returns 0 Frames downstream) â always use `$f->set('slot', val)` â `chorus-engine §5`
- [ ] â **CONDITION too restrictive on `type_element`** â silently excludes Frames of other types â prefer testing slot presence â `chorus-engine §5`
- [ ] â **Conditional ACTION without `else`** â returns `1` even when nothing modified â infinite loop at scale â always `return 1` inside the `if`, `0` as fallback â `chorus-engine §5`
- [ ] Use `|` (block scalar) for multi-line `ACTION` â never `>`
- [ ] Files named `R<NN>-<slug>.yml` (alphabetical = load order)
- [ ] â **Termination via global `fmatch` in YAML** â guaranteed infinite loop â use pure Perl `addrule()` instead (see `chorus-check.md` Phase 3)
- [ ] If `PREMISES` present: consistent with the KB `Slot dictionary`
### Phase 5.5 â Generate Perl Helpers
For each agent whose KB contains a non-empty `Perl Helpers` section,
create `$SANDBOX/lib/<Namespace>/Agent/<Slug>/Helpers.pm`.
**Criteria for including a helper here:**
The code encodes knowledge extracted from the corpus:
- normative value tables (e.g. resistances by class NF EN 338)
- regulatory calculations (e.g. EC5 §6.3 formula)
- threshold or range from a standard article
**What is NOT a knowledge helper** (â stays in `chorus-check`):
- file parsing, database access, network calls
- orchestration logic (loops over agents, error handling)
#### Template `Helpers.pm`
```perl
package <Namespace>::Agent::<Slug>::Helpers;
use strict;
use warnings;
use Exporter 'import';
# Exhaustive list of exported helpers â chorus-check imports them all
our @EXPORT_OK = qw(
<helper1>
<helper2>
);
# -------------------------------------------------------
# <helper1>
# Source corpus : §<N> â <titre section>
# -------------------------------------------------------
# Signature : <helper1>(<args>) â <type retour>
# Called by: R<NN>-<slug>.yml (ACTION)
sub <helper1> {
my (<args>) = @_;
# <corps extrait du corpus>
}
# -------------------------------------------------------
# <helper2>
# Source corpus : §<N> â <titre section>
# -------------------------------------------------------
sub <helper2> {
my (<args>) = @_;
# <corps extrait du corpus>
}
1;
```
#### Generation rules
- **One `Helpers.pm` file per agent** â even if there is only one helper.
- **Exhaustive `@EXPORT_OK`** â all helpers listed, none missing.
`chorus-check` does a full `use ... qw(...)` to make them available
in the namespace before `loadRules()`.
- **`Source corpus` comment** on each helper â traceability to the standard.
- **â ï¸ Org KB parity â mandatory:** after writing `Helpers.pm`, immediately
update (or write for the first time) the `Perl Helpers` section of
`agent/chorus/<slug>.org` with the **exact same numeric values and defaults**.
The org KB is the single source of truth for `chorus-create-project`;
a divergence here silently corrupts all generated JSON files.
- If a helper is **shared between multiple agents** â place it in
`lib/<Namespace>/Helpers/Shared.pm` and document it in the KB of
both agents involved.
- **No side effects** in a helper: no slot writes, no call to
( run in 0.775 second using v1.01-cache-2.11-cpan-c966e8aa7e8 )