/hns-lsel-curator
Local Self-Evolution Loop (LSEL) curator — the CLUSTER + drain engine for the GOOS-local PROPOSE→APPLY seam closure (SPEC-LSEL-LOCAL-EVOLUTION-001). Companion-offset drain of .moai/lessons-inbox.jsonl with a drain-side severity filter that drops the ~65% Bash-timeout/sandbox
$ npx -y skills add modu-ai/moai-adk --skill hns-lsel-curator --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/hns-lsel-curator
Context preview
The summary Claude sees to decide when to auto-load this skill.
Local Self-Evolution Loop (LSEL) curator — the CLUSTER + drain engine for the GOOS-local PROPOSE→APPLY seam closure (SPEC-LSEL-LOCAL-EVOLUTION-001). Companion-offset drain of .moai/lessons-inbox.jsonl with a drain-side severity filter that drops the ~65% Bash-timeout/sandbox
SKILL.md
hns-lsel-curator.SKILL.mdname: hns-lsel-curator
description: >
Local Self-Evolution Loop (LSEL) curator — the CLUSTER + drain engine for the
GOOS-local PROPOSE→APPLY seam closure (SPEC-LSEL-LOCAL-EVOLUTION-001). Companion-offset
drain of .moai/lessons-inbox.jsonl with a drain-side severity filter that drops the ~65%
Bash-timeout/sandbox noise, event_key clustering with a frequency gate, and a
Generative-Agents-style 1-10 importance score. Candidates stage at
.moai/state/lsel/clusters.json. M1 = drain only (NO PROPOSE, NO APPLY, NO memory/ writes).
allowed-tools: Read, Grep, Glob, Bash
user-invocable: false
metadata:
version: "0.1.0"
category: "harness"
status: "active"
updated: "2026-08-04"
tags: "lsel,self-evolution,drain,cluster,harness,dogfood"
hns-lsel-curator — LSEL CLUSTER + drain engine
> **Namespace:** `hns-lsel-*` is user-owned dogfood (CLAUDE.local.md §24). This skill is > NOT mirrored into `internal/template/templates/` — it lives only in this repo. Graduation > to `moai-lsel-*` + 16-language distribution is a separate SPEC (out of scope per spec.md §G). > > **M1 scope:** drain + cluster + stage candidates. NO APPROVE, NO APPLY (M3). > **M2 scope:** drain + cluster + **PROPOSE shadow** (no APPROVE, no APPLY). The PROPOSE stage > emits shadow proposals + self-critiques; APPROVE/APPLY land in M3 via the fresh > `hns-lsel-applier` path. M2 does NOT write to `memory/` — the first `feedback_*.md` topic > file is an M3+ deliverable after APPROVE.
What this skill does
The MoAI-ADK repo accumulates tool-failure stubs in `.moai/lessons-inbox.jsonl` (624 stubs at M1 start, re-measured — a moving target). The constitution names the orchestrator as the drain actor, but until this skill there was **zero mechanical drain code** — the drain existed only as a doctrine paragraph (`moai-constitution.md:147`). This skill closes that gap in user-owned surfaces, without touching the frozen Go applier (`internal/harness/applier.go:22` — its write-flag stays `false`; REQ-LSEL-003: bypass, never unfreeze).
The drain is split into a **mechanical core** (`drain.sh`, deterministic, testable) and a **model-mediated layer** (this SKILL.md + your judgment, invoked for M2+ importance refinement and proposal drafting).
The mechanical core — `drain.sh`
`drain.sh` is a portable bash + jq script that lives next to this SKILL.md. It performs the deterministic half of the drain:
drain.sh --inbox <path-to-lessons-inbox.jsonl> --state-dir <path-to-lsel-state>
Pipeline (REQ-LSEL-009 + AC-LSEL-009 / AC-LSEL-010):
1. **Companion offset** — read `<state-dir>/drain-offset.json` (seed `{"offset":0}` if absent). The inbox is append-only and is NEVER mutated; the offset marks consumed stubs (SPEC-HARNESS-RATCHET-REWIRE-001 D3 companion-offset pattern). 2. **Slice** — read stubs from the offset onwards (`tail -n +<offset+1>`). 3. **Drain-side severity filter** (AC-LSEL-010) — discard noise BEFORE clustering:
- `tool_failure:Bash:UnknownFailure` — the opaque ~65% timeout/sandbox bucket (the dominant
noise share; report §2).
- `tool_failure:Bash:SandboxViolation` — environment constraint, not a code defect.
- any `*:TimeoutError` (Bash + MCP timeouts).
The filter is drain-side because `internal/hook/failure_observer.go` (the inbox writer) is OUTSIDE the six loop-writable surfaces (plan.md §F.1 [DECISION RESOLVED]), so the loop cannot edit the writer — it filters on read instead. 4. **Cluster** by `event_key` with frequency count, first/last seen, and up to 3 sample summaries. 5. **Singleton gate** — discard clusters with `frequency < 2` (single-occurrence noise per the constitution Lessons Protocol drain paragraph). 6. **Importance** — score each survivor with a Generative-Agents-style 1-10 gate: `importance = min(10, frequency)` (frequency as proxy; the model augments this in M2+ with a severity hint and retrieval-weighted judgment). 7. **Emit** candidates to `<state-dir>/clusters.json`; advance the companion offset.
`clusters.json` schema
{
"drained_at": "2026-08-04T08:41:00Z",
"offset_before": 0,
"offset_after": 624,
"total_read": 624,
"noise_discarded": 533,
"singletons_discarded": 4,
"candidates": [
{
"event_key": "tool_failure:Agent:UnknownFailure",
"frequency": 41,
"first_seen": "...",
"last_seen": "...",
"sample_summaries": ["...", "...", "..."],
"source": "tool:Agent",
"importance": 10
}
]
}Empty-delta no-op
If the inbox has not grown past the offset, `drain.sh` writes an empty-candidate `clusters.json` and leaves the offset unchanged. Not a failure (acceptance.md §E edge case).
The model-mediated layer (you, when invoked)
`drain.sh` produces the deterministic candidate set. When this skill is invoked for a real curation pass (M2+), your job on top of the mechanical output is:
- **Read `clusters.json`** and rank candidates by `importance` then `frequency`.
- **Augment importance** with a severity hint the mechanical core cannot see: a recurring
`Bash:ExitError` cluster points at a real command-shape defect (high signal); a recurring `Agent:ContextCancelled` cluster may be session-teardown noise (lower signal). Record the rationale in the candidate's prose when you draft the M2 proposal — do NOT rewrite `clusters.json` (it is the mechanical artifact; your augmentation lives in the proposal).
- **Do NOT write to `memory/` in M1.** Candidates stage in `clusters.json` only. The first
`feedback_*.md` topic file is produced by the M2 PROPOSE stage after retrieval-before-propose and self-critique (REQ-LSEL-010).
What this skill does NOT do (M1 boundaries)
- **No APPROVE / APPLY** — the parallel user-owned applier (`hns-lsel-applier`) is M3.
- **No edits to frozen doctrine** — `.claude/rules/moai/**`, `CLAUDE.md`,
`internal/template/templates/**`, retained agents, `moai-*` skills, and the frozen Go applier / `curator_dispatch.go` are all byt
Read more
name: hns-lsel-curator description: > Local Self-Evolution Loop (LSEL) curator — the CLUSTER + drain engine for the GOOS-local PROPOSE→APPLY seam closure (SPEC-LSEL-LOCAL-EVOLUTION-001). Companion-offset drain of .moai/lessons-inbox.jsonl with a drain-side severity filter that drops the ~65% Bash-timeout/sandbox noise, event_key clustering with a frequency gate, and a Generative-Agents-style 1-10 importance score. Candidates stage at .moai/state/lsel/clusters.json. M1 = drain only (NO PROPOSE, NO APPLY, NO memory/ writes). allowed-tools: Read, Grep, Glob, Bash user-invocable: false metadata: version: "0.1.0" category: "harness" status: "active" updated: "2026-08-04" tags: "lsel,self-evolution,drain,cluster,harness,dogfood"
hns-lsel-curator — LSEL CLUSTER + drain engine
> **Namespace:** `hns-lsel-*` is user-owned dogfood (CLAUDE.local.md §24). This skill is > NOT mirrored into `internal/template/templates/` — it lives only in this repo. Graduation > to `moai-lsel-*` + 16-language distribution is a separate SPEC (out of scope per spec.md §G). > > **M1 scope:** drain + cluster + stage candidates. NO APPROVE, NO APPLY (M3). > **M2 scope:** drain + cluster + **PROPOSE shadow** (no APPROVE, no APPLY). The PROPOSE stage > emits shadow proposals + self-critiques; APPROVE/APPLY land in M3 via the fresh > `hns-lsel-applier` path. M2 does NOT write to `memory/` — the first `feedback_*.md` topic > file is an M3+ deliverable after APPROVE.
What this skill does
The MoAI-ADK repo accumulates tool-failure stubs in `.moai/lessons-inbox.jsonl` (624 stubs at M1 start, re-measured — a moving target). The constitution names the orchestrator as the drain actor, but until this skill there was **zero mechanical drain code** — the drain existed only as a doctrine paragraph (`moai-constitution.md:147`). This skill closes that gap in user-owned surfaces, without touching the frozen Go applier (`internal/harness/applier.go:22` — its write-flag stays `false`; REQ-LSEL-003: bypass, never unfreeze).
The drain is split into a **mechanical core** (`drain.sh`, deterministic, testable) and a **model-mediated layer** (this SKILL.md + your judgment, invoked for M2+ importance refinement and proposal drafting).
The mechanical core — `drain.sh`
`drain.sh` is a portable bash + jq script that lives next to this SKILL.md. It performs the deterministic half of the drain:
drain.sh --inbox <path-to-lessons-inbox.jsonl> --state-dir <path-to-lsel-state>
Pipeline (REQ-LSEL-009 + AC-LSEL-009 / AC-LSEL-010):
1. **Companion offset** — read `<state-dir>/drain-offset.json` (seed `{"offset":0}` if absent). The inbox is append-only and is NEVER mutated; the offset marks consumed stubs (SPEC-HARNESS-RATCHET-REWIRE-001 D3 companion-offset pattern). 2. **Slice** — read stubs from the offset onwards (`tail -n +<offset+1>`). 3. **Drain-side severity filter** (AC-LSEL-010) — discard noise BEFORE clustering:
- `tool_failure:Bash:UnknownFailure` — the opaque ~65% timeout/sandbox bucket (the dominant
noise share; report §2).
- `tool_failure:Bash:SandboxViolation` — environment constraint, not a code defect.
- any `*:TimeoutError` (Bash + MCP timeouts).
The filter is drain-side because `internal/hook/failure_observer.go` (the inbox writer) is OUTSIDE the six loop-writable surfaces (plan.md §F.1 [DECISION RESOLVED]), so the loop cannot edit the writer — it filters on read instead. 4. **Cluster** by `event_key` with frequency count, first/last seen, and up to 3 sample summaries. 5. **Singleton gate** — discard clusters with `frequency < 2` (single-occurrence noise per the constitution Lessons Protocol drain paragraph). 6. **Importance** — score each survivor with a Generative-Agents-style 1-10 gate: `importance = min(10, frequency)` (frequency as proxy; the model augments this in M2+ with a severity hint and retrieval-weighted judgment). 7. **Emit** candidates to `<state-dir>/clusters.json`; advance the companion offset.
`clusters.json` schema
{
"drained_at": "2026-08-04T08:41:00Z",
"offset_before": 0,
"offset_after": 624,
"total_read": 624,
"noise_discarded": 533,
"singletons_discarded": 4,
"candidates": [
{
"event_key": "tool_failure:Agent:UnknownFailure",
"frequency": 41,
"first_seen": "...",
"last_seen": "...",
"sample_summaries": ["...", "...", "..."],
"source": "tool:Agent",
"importance": 10
}
]
}Empty-delta no-op
If the inbox has not grown past the offset, `drain.sh` writes an empty-candidate `clusters.json` and leaves the offset unchanged. Not a failure (acceptance.md §E edge case).
The model-mediated layer (you, when invoked)
`drain.sh` produces the deterministic candidate set. When this skill is invoked for a real curation pass (M2+), your job on top of the mechanical output is:
- **Read `clusters.json`** and rank candidates by `importance` then `frequency`.
- **Augment importance** with a severity hint the mechanical core cannot see: a recurring
`Bash:ExitError` cluster points at a real command-shape defect (high signal); a recurring `Agent:ContextCancelled` cluster may be session-teardown noise (lower signal). Record the rationale in the candidate's prose when you draft the M2 proposal — do NOT rewrite `clusters.json` (it is the mechanical artifact; your augmentation lives in the proposal).
- **Do NOT write to `memory/` in M1.** Candidates stage in `clusters.json` only. The first
`feedback_*.md` topic file is produced by the M2 PROPOSE stage after retrieval-before-propose and self-critique (REQ-LSEL-010).
What this skill does NOT do (M1 boundaries)
- **No APPROVE / APPLY** — the parallel user-owned applier (`hns-lsel-applier`) is M3.
- **No edits to frozen doctrine** — `.claude/rules/moai/**`, `CLAUDE.md`,
`internal/template/templates/**`, retained agents, `moai-*` skills, and the frozen Go applier / `curator_dispatch.go` are all byt
Agentic development harness for Claude Code — SPEC-driven plan/run/sync, TRUST 5 quality gates, model+effort routing, and Claude×GLM multi-LLM cost control. Single Go binary, 16 languages, zero deps.
Repo: modu-ai/moai-adk
Other skills on moai-adk.
- /hns-lsel-applier
Local Self-Evolution Loop (LSEL) APPLY engine — the playback-only consumer of approved decision.json records that drives `.moai/hooks/lsel-apply.sh` for the GOOS-local PROPOSE→APPLY seam closure (SPEC-LSEL-LOCAL-EVOLUTION-001 M3). Reads an approved decision.json, validates the
Open skill - /hns-moaiadk-best-practices
moai-adk-go best-practices reference for the 4 harness specialists (cli-template-specialist, quality-specialist, workflow-specialist, hook-ci-specialist). Covers TRUST 5 gates, Go test isolation (t.TempDir, no OTEL env in parallel tests), hardcoding-prevention rules (env
Open skill - /hns-moaiadk-dev-reference
moai-adk-go local dev reference — version management/release process (sec 5), shell-script hook development (sec 7), build & dev commands (sec 10). Load only when performing these specific tasks.
Open skill - /hns-moaiadk-patterns
moai-adk-go domain-patterns reference for the 4 harness specialists (cli-template-specialist, quality-specialist, workflow-specialist, hook-ci-specialist). Covers the CLI/template/config/hook/spec subsystem architecture, key source paths, the Pipeline specialist delegation map,
Open skill - /hns-oss-docs-i18n-rules
HARD i18n rules digest for the oss-docs harness specialists working on moai-adk-go README 4-locale set and the docs-site (adk.mo.ai.kr). Covers the canonical-locale chains, the 4-locale same-PR obligation, Mermaid TD-only, the no-emoji + icon-shortcode rule, emphasis-marker
Open skill - /hns-oss-docs-readme-sync
README 4-file synchronization procedure for the oss-docs harness: English README.md as primary source, ko/ja/zh derivation, the shared language-switcher header contract, section-order parity checklist, and the manual verification recipe (no linter exists for READMEs). Loaded by
Open skill

