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 )