Generate, update, validate, and implement LOI (Library of Intent) indices. Handles full index generation, incremental updates, codetect-based scaffolding, validation, and bi-directional intent sync (code ↔ index). Uses parallel Agent workers for generation.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Generate, update, validate, and implement LOI (Library of Intent) indices. Handles full index generation, incremental updates, codetect-based scaffolding, validation, and bi-directional intent sync (code ↔ index). Uses parallel Agent workers for generation.
triggers
["/loi-generate","/loi generate","/loi update","/loi validate","/loi implement","generate loi","full loi","rebuild index","update loi","refresh loi","refresh index","incremental update","full codebase index","implement loi changes","sync intent to code"]
/loi implement, "implement loi changes", "sync intent to code"
Implement
/loi validate
Validate
"Rebuild" without further context means Full-Generate.
Full-Generate Mode
Build a complete index from scratch. Use for first-time setup or major architectural shifts.
When to use: First-time setup, user requests "generate full loi", "rebuild entire index", or for large codebases where incremental updates miss structural changes.
Process
Invoke the RLM skill (via Skill tool with skill: "rlm") for all discovery and generation steps. Do NOT run bash file discovery commands directly — delegate to RLM.
1. Discover ALL source directories via RLM Index & Filter phase:
Use RLM's Phase 1 (Native Mode) to census the repo:
Glob **/*.go, **/*.ts, **/*.tsx, **/*.py, **/*.js, **/*.rb (adapt per project)
Use RLM's fd/rg tools (falling back to find/grep) to count files per directory and identify top-level subdomain boundaries
Every top-level directory with source files MUST be included. Non-standard directories (packages/, engines/, gems/) often contain more code than app/ or src/. Omitting them produces a partial index.
NO SAMPLING. Do not pick "representative" directories. Every source directory discovered in step 1 must be assigned to a room. If the census finds N directories, all N must appear in the index.
2. Build a coverage checklist before writing any files — After the census, produce a flat list of every source directory with its file count. This is your ground truth. Assign each directory to a room before proceeding. Do not write any index files until every directory has a room assignment.
Use these as starting points — rename to match the codebase's actual language:
Subdomain
What lives here
Example rooms
infra/
Boot, config, DI, migrations, server wiring
startup.md, config.md, migrations.md
identity/
Auth, sessions, users, roles, permissions
auth_flow.md, permissions.md, users.md
api/
HTTP/gRPC/GraphQL handlers, middleware, routing
routes.md, middleware.md, serializers.md
data/
Repositories, queries, ORM models, caching
repositories.md, models.md, cache.md
integrations/
External API clients, webhooks, SDKs
stripe.md, aws.md, email.md
workers/
Background jobs, queues, cron, event consumers
jobs.md, consumers.md, schedulers.md
shared/
Logging, errors, formatters, test helpers
errors.md, logging.md, utilities.md
<business>/
Core business logic (name after the domain)
catalog/, orders/, fulfillment/
Splitting Rules
Subdomains are the default. Every codebase gets at least infra/ and one business domain.
Flat top-level domain files are the exception — only for tiny groups (<5 files) that don't warrant a folder. Example: a single config.md at the top level is fine if there are only 2 config files.
Never split by alphabet.A-M.md / N-Z.md is meaningless. Always split by functional concern.
Room file size limit: ~150 entries. If a room would exceed this, split it into multiple rooms within the same building.
Business logic gets its own building. If the codebase serves multiple business domains (catalog, orders, fulfillment), each gets a subdomain folder — not one giant business.md.
Merge tiny rooms (<3 files) into the nearest neighbor. Don't create a room for 1 file.
Never create a building with only one room. If a subdomain folder would contain only _root.md + one .md room file, the folder adds navigation overhead with no benefit. Instead, promote the room to a flat top-level file (e.g., docs/index/config.md rather than docs/index/config/_root.md + docs/index/config/general.md). A building needs at least 2 room files to justify its own folder.
Shared utilities go in shared/ or infra/, not in their primary consumer's room. If readlimit/ is used by mirrors, scanning, and API handlers, it belongs in infra/ or shared/ — not in proxy/. Place a file where its responsibility lives, not where its biggest caller lives.
4.5. Scaffold mechanical fields — If the project has a codetect index (.codetect/symbols.db), run the scaffold command to pre-populate SYMBOLS, TYPE, and DEPENDS from AST data:
loi generate --scaffold
This produces room files with <!-- LLM-FILL --> markers where the LLM must fill in DOES, PATTERNS, USE WHEN, EMITS, and CONSUMERS. If no codetect index exists, skip this step and generate entries manually in step 5.
5. Generate (via RLM Skill with Consensus Loop) — Use RLM's parallel processing with a 3-step pipeline: Map -> Critique -> Reduce.
IMPORTANT — Scaffolded rooms: If step 4.5 produced room files with <!-- LLM-FILL --> markers, the Map phase MUST preserve existing SYMBOLS, DEPENDS, and TYPE fields and ONLY fill in the markers. Do NOT regenerate or rewrite fields that the scaffold already populated. Read each room file first and replace only the <!-- LLM-FILL: ... --> comments with the appropriate content.
Phase A (Map): Spawn one worker agent per room. Prompt: "Read all files in [file list]. If the room file already exists with <!-- LLM-FILL --> markers, preserve all existing fields (SYMBOLS, DEPENDS, TYPE) and only fill in the marked fields. Otherwise, produce a LOI entry for each file following reference/FORMAT_REFERENCE.md.
CRITICAL — use this exact entry format (no bullets, no bold, no markdown formatting on field names):
# filename.go
DOES: One or two sentences describing what this file does specifically.
SYMBOLS:
- ExportedFunc(ctx context.Context, id string) (Result, error)
- unexportedFunc(input Input) error
- Types: StructA, StructB (+4 more)
TYPE: MainStruct { field1, field2, field3 }
DEPENDS: internal/audit, internal/config (+2 more)
PATTERNS: middleware-chain, token-bucket
USE WHEN: Choosing between this and alternative.go for X.
Format rules — violations will be rejected by the Committee:
Fields are plain FIELDNAME: — never - **FIELDNAME**: or **FIELDNAME**:
SYMBOLS are list items (- ) with full signatures including params and return types — never comma-separated names on one line
Entries separated by ---
Entries alphabetized by filename within each room
No PATH: field — the # filename.ext heading is the path
Content rules:
DEPENDS: Trace import/require statements for cross-package internal imports. Omit stdlib and same-package. Cap at 4 items.
EMITS: If the file publishes events, emits to channels, calls webhook delivery, or invokes callback functions that notify other subsystems, add EMITS.
PROPS/HOOKS: For React/Vue components, extract component props into PROPS and custom hooks/composables into HOOKS.
PATTERNS: Name only, no parenthetical explanations.
SYMBOLS: Functions (exported and unexported) with full signatures. Group types — never list each one. Use shortest same-repo paths for DEPENDS; keep full paths for external repos.
TYPE: Only for actual struct/class definitions, not file categories.
DOES: 1-2 sentences max."
Phase B (Critique / The Committee): Pass the mapped drafts to specialized personas before finalizing:
Architect Persona: "Does this room mix concerns? (e.g., HTTP parsing next to database logic). If yes, set architectural_health: warning or critical and write a committee_notes explanation."
Security Persona: "Does this room handle raw SQL, PII, or auth tokens? If yes, set security_tier: sensitive or high."
Completeness Persona: "For each entry: (1) Are DEPENDS fields present for all cross-domain imports? (2) Are EMITS fields present for event/callback publishers? (3) For frontend components, are PROPS and HOOKS populated? (4) Are all behavioral PATTERNS named? Flag omissions."
Brevity Persona: "For each entry: (1) Are fields plain FIELDNAME: format — not - **FIELDNAME**: bullets? (2) Are SYMBOLS list items (- ) with full signatures — not comma-separated names on one line? (3) Are entries separated by --- and alphabetized by filename? (4) Is there a PATH: field? (reject — heading is the path). (5) Do SYMBOLS group types instead of listing individually? (6) Are same-repo DEPENDS using shortest paths? Max 4 items. (7) Are PATTERNS name-only? (8) Is DOES 1-2 sentences max? Flag violations."
Phase C (Reduce): "Merge the critiqued LOI outputs into the subdomain structure. At the top of each room file, generate the YAML metadata header including see_also, hot_paths, and the exact Governance Flags determined in Phase B. All rooms MUST have architectural_health and security_tier fields — including test and utility rooms (use normal when no issues are flagged). Build docs/index/_root.md with task/pattern mapping tables."
Agent count: spawn one worker agent per room, plus the Committee personas for the Critique phase. If /rlm is unavailable, fall back to spawning one background Agent per subdomain to simulate the Committee.
5.5. Cross-room symbol collision pass — After Phase C produces all room content but before writing any files, scan for symbol name collisions across rooms and annotate each conflicting entry.
How:
For each room, extract the bare function/method name from every SYMBOLS line by stripping receiver, params, and return types. Examples: (p *Persist) CreateMessageLog(ctx context.Context, input CreateMessageLogInput) (MessageLog, error) → CreateMessageLog; CreateMessageLog(ctx context.Context, p Persister, input persist.CreateMessageLogInput) (persist.MessageLog, error) → CreateMessageLog.
Build an inverted map: bare_name → [(room_file, full_signature, source_file_heading)].
For every bare name that maps to 2+ rooms: append a DISAMBIGUATION: line to the relevant entry in each room. The note must:
Name the other source file and room
State the key behavioral difference in one sentence
Give a concrete routing hint for when to choose the other room
Example:
DISAMBIGUATION: There is also a package-level `CreateMessageLog` in `internal/temporal/shared/activities.go` (`workers/temporal_core.md`) that wraps this DB method and classifies errors for Temporal retry (non-1062 → retryable wrapped error; 1062 → non-retryable). If the question is about error behaviour, retryability, or Temporal, load `workers/temporal_core.md` instead.
In Incremental-Generate, run this pass only for regenerated rooms plus any rooms whose SYMBOLS now collide with them.
6. Write index files:
docs/index/_root.md — Campus map (see format below)
docs/index/<subdomain>/_root.md — Building router per subdomain
docs/index/<subdomain>/<room>.md — Domain files with flat entry lists
If scaffolded rooms exist: Update them in-place (fill markers, update metadata header). Do NOT overwrite the entire file — preserve scaffold-generated SYMBOLS, DEPENDS, and TYPE.
7. Verify coverage — Cross-check the coverage checklist from step 2 against the written index files. Every directory on the checklist must appear in at least one room file. If any remain uncovered, generate those rooms before declaring the index complete.
Regenerate only stale rooms — If the project has a codetect index, run loi generate --scaffold --room <room> for each stale room to refresh SYMBOLS/DEPENDS from AST. Then invoke /rlm (via the Skill tool with skill: "rlm") with only the stale rooms as map inputs to fill semantic fields; if /rlm is unavailable, spawn agents manually per room.
Update routers — Refresh _root.md entries (both campus and building level) for any changed rooms.
Implement Mode (Bi-Directional Sync)
Reverse the flow: edits to the markdown index drive changes in source code. The LOI becomes an executable contract.
When to use: User edits a DOES, SYMBOLS, or other intent field in a docs/index/ room file and wants the source code updated to match the new intent. Triggered by /loi implement, "implement loi changes", or "sync intent to code".
Process
1. Detect intent delta — Diff the modified room file against its last committed version:
git diff HEAD -- docs/index/<subdomain>/<room>.md
Parse the diff to extract changed entries. For each changed entry, identify:
File path: The # filename.ext heading (deterministic — the LOI maps every entry to an exact source file)
Old intent: Previous DOES, SYMBOLS, TYPE, INTERFACE, PATTERNS values
New intent: Updated values from the markdown
If no intent fields changed (e.g., only whitespace or see_also), skip that entry.
2. Validate the delta — Before touching source code:
Confirm every referenced source file exists on disk. If a file was deleted or renamed, flag it and halt for that entry.
Check that the new intent is actionable (not empty, not identical to old).
3. Create an implementation branch:
git checkout -b loi/implement-<room>-<timestamp>
Never work directly on the current branch. All changes happen on a dedicated branch.
4. Implement changes — For each changed entry, construct a worker prompt:
The Architect has updated the Contract for <source-file>.
Old Intent: <old DOES value>
New Intent: <new DOES value>
Old Symbols: <old SYMBOLS, if changed>
New Symbols: <new SYMBOLS, if changed>
Task: Read <source-file>. Refactor the code to fulfill the New Intent.
- Preserve existing function signatures unless the New Intent explicitly demands changes.
- Add new functions/types if the New Symbols field includes them.
- Do not remove existing exports unless the New Intent removes their purpose.
- Follow existing code style and patterns in the file.
For large rooms with many changed entries, use the RLM skill (skill: "rlm") to parallelize — one worker agent per changed entry. If RLM is unavailable, process entries sequentially.
5. Run the test suite — After all source changes are written:
# Detect project type and run appropriate tests# Go: go test ./...# Node: npm test# Python: pytest
If tests fail:
Read the failure output. Attempt a fix (max 2 retries).
If tests still fail after retries, do not commit. Report the failures and leave the branch for human review.
6. Update the LOI index — Regenerate the room file for any source files that were modified (the code may have gained new symbols, types, etc. beyond what the user specified). This keeps the index in sync with reality.
Body: Table of old → new intents, list of modified source files, test results
Label: loi-implement
The PR requires human approval before merge. The AI never merges its own work.
Safety Rails
Branch isolation: All changes happen on a fresh branch. The working branch is never modified.
Test gate: Code is only committed if the test suite passes.
No force-push: Never use --force. If the branch exists, create a new one with an incremented timestamp.
Human approval: PRs are opened for review, never auto-merged.
Atomic entries: Each entry (source file) is implemented independently. A failure in one entry does not block others.
Automation Options
The /loi implement command is the IDE-native way (Option A). Two additional automation hooks are provided:
Option B — Pre-Commit Hook: install with loi setup-hook --mode pre-commit-stale. Warns when staged source files are covered by a LOI room that wasn't also updated in the commit.
Option C — Background Daemon: loi watch monitors docs/index/ for changes with three modes:
--mode notify (default): validate → create draft PR → notification. No code changes until you approve.
--mode auto: validate → implement via AI → run tests → commit → PR. Full autonomy, opt-in.
--mode dry-run: log only.
# Notify mode — Slack webhook
loi watch --notify-backend slack --notify-url https://hooks.slack.com/services/...
# Notify mode — write events to a JSONL file
loi watch --notify-backend file --notify-file loi-events.jsonl
# Notify mode — POST to a custom HTTP endpoint
loi watch --notify-backend webhook --notify-url https://example.com/loi-hook
# Auto mode — create PR but never invoke implement worker (safest auto option)
loi watch --mode auto --policy draft-only --notify-backend slack --notify-url https://...
# Auto mode — implement only test files; block on sensitive rooms
loi watch --mode auto --policy tests-safe --notify-backend webhook --notify-url https://...
# Auto mode — implement within explicit scopes only
loi watch --mode auto --policy scoped-code-safe \
--allowed-scopes "docs/**,tests/**" --notify-backend slack --notify-url https://...
# Auto mode — full autonomy, disable governance blocking
loi watch --mode auto --policy full-auto \
--block-governance-security none --notify-backend slack --notify-url https://...
Policy tiers (controls what --mode auto is allowed to implement):
Policy
Behaviour
notify-only
Validate + notify; worker never invoked
draft-only
Branch + draft PR created; worker not invoked
docs-safe
Implement only if all source files are under docs/
tests-safe
Implement only if all source files are test files
scoped-code-safe
Implement only within --allowed-scopes globs
full-auto
No scope restriction (default)
Regardless of policy, auto-implement is always blocked if a changed room has security_tier matching --block-governance-security (default: sensitive) or architectural_health: critical. A conflicting room claim from another agent also blocks the worker.
See the README for setup instructions.
Validate Mode
Verify the structural integrity and coverage of a generated LOI index.
When to use: After generating or updating an index, or when /loi validate is triggered.
Process:
loi validate
Checks:
docs/index/_root.md exists and has TASK → LOAD table
All subdomain _root.md routers exist and reference valid room files
All room .md files have YAML frontmatter with required fields (room, see_also)
Every room file referenced in a router actually exists on disk
Every source directory with code files is covered by at least one room
No room exceeds ~150 entries
Changed-rooms mode — validate only rooms touched in the current git diff:
loi validate --changed-rooms
CI mode — treat warnings as errors:
loi validate --ci
Install git hooks:
loi setup-hook # install all hooks (pre-push + pre-commit-stale)
loi setup-hook --mode pre-push # pre-push only
loi setup-hook --force # overwrite existing hooks
Fix any reported errors before considering the index complete.
Pattern Validation
Verify that every PATTERN entry in _root.md files is semantically grounded in the room it points to.
loi validate-patterns
loi validate-patterns --level 2
Levels:
1 (default) — Pattern label (normalized) must appear in the target room body.
2 — Also checks pattern_aliases frontmatter and pattern_metadata freshness (last_validated within 14 days).
Output categories:
ERRORS — Target room file missing entirely.
ORPHANED PATTERNS — Label not found in room body and no aliases match.
WARNINGS — Alias-only support, or last_validated is stale (>14 days).
Table Diff
Compute row-level deltas for TASK, PATTERN, and GOVERNANCE tables between two git revisions.
loi diff-tables docs/index/auth/_root.md
loi diff-tables docs/index/_root.md --from HEAD~3 --to HEAD
The watcher daemon calls this automatically and attaches the table diff to Slack/webhook notifications when a _root.md file changes.
Governance Aggregation
Aggregate GOVERNANCE WATCHLIST entries from all _root.md files, sorted by combined severity (security + health).
loi governance
loi governance --security sensitive
loi governance --health warning
loi governance --format json
# Multi-repo fleet view
loi governance /repos/alpha /repos/beta /repos/gamma
Also surfaces rooms with non-normal architectural_health or security_tier frontmatter flags that aren't already covered by a watchlist entry.
Runtime Coordination (Room Claims)
Advisory-first coordination so multiple agents avoid editing the same room simultaneously. Claims are stored in .loi-claims.json at the project root (gitignored).
# Claim a room before editing it
loi claim auth/ucan.md --intent edit --ttl 15m
# Extend your claim while working
loi heartbeat auth/ucan.md
# Release when done
loi release auth/ucan.md
# Check who holds a claim
loi status auth/ucan.md --include-freshness
# Record a handoff summary
loi summary auth/ucan.md "Working on TTL path in MintToken"# List all active claims
loi claims
loi claims --repo my-repo
Conflict matrix: edit + edit = conflict (blocked); security-sweep + edit = governance-sensitive (warning). All other combinations allow with optional visibility notice.
Proposal Provenance
Query and validate AI-generated improvement proposals stored under docs/index/proposals/.
# List all proposals
loi proposals
# Filter by room, grader version, or failure reason
loi proposals --target-room auth/ucan.md
loi proposals --grader-version v2.3
loi proposals --failure-reason REFUSAL_CONTEXT
# Validate all proposals for required metadata fields
loi proposals --validate
Each proposal file must contain a proposal_metadata: block. See reference/FORMAT_REFERENCE.md → Schema Extensions for the full field reference.