Architecture¶
ai-rizz is a single-file POSIX shell CLI that reconciles rule repository entries into Cursor's active configuration directories.
The mental model:
- Commands mutate manifests.
- Sync rebuilds generated Cursor directories from those manifests.
- The source repository cache is implementation detail, not user-facing state.
The rest of this page describes the cross-cutting flow. Specifics — manifest schema, cache paths, mode-specific output directories, conflict-resolution rules — live on their own pages and are linked inline.
System Shape¶
graph TD
classDef cli fill:#1e88e5,fill-opacity:0.16,stroke:#1e88e5,stroke-width:1.5px;
classDef state fill:#8e24aa,fill-opacity:0.16,stroke:#8e24aa,stroke-width:1.5px;
classDef cache fill:#f57c00,fill-opacity:0.16,stroke:#f57c00,stroke-width:1.5px;
classDef output fill:#2e7d32,fill-opacity:0.16,stroke:#2e7d32,stroke-width:1.5px;
User["Developer"] --> CLI["ai-rizz CLI"]:::cli
CLI -->|"reads & writes"| Manifests["Mode Manifests"]:::state
CLI -->|"clones & pulls"| Cache["Source Repository Cache"]:::cache
Manifests -->|"desired state"| Sync["sync_all_modes()"]:::cli
Cache -->|"source files"| Sync
Sync -->|"writes"| Output["Cursor Output Tree"]:::output
- Mode Manifests are the durable, user-facing state. Schema and file locations: Manifest Files.
- Source Repository Cache is a local clone that backs all reads. Layout: Rules Cache.
- Cursor Output Tree is regenerated by
syncand should be treated as deploy output. Per-mode destinations: Rule Modes.
Command Flow¶
Most commands follow the same shape: validate state, pick a mode, mutate a manifest, then reconcile generated files.
sequenceDiagram
participant U as Developer
participant C as Command Handler
participant M as Manifest File
participant G as Source Cache
participant S as Sync Reconciler
participant O as Cursor Output
U->>C: ai-rizz add rule foo --local
C->>C: validate initialization and manifest integrity
C->>C: select or lazily initialize mode
C->>G: clone or pull source repository
C->>M: add desired entry
C->>S: sync_all_modes()
S->>S: resolve conflicts
S->>O: clear managed output for active modes
S->>G: copy manifest entries from cache
S-->>U: success message
add and remove are intentionally manifest-first. They do not surgically edit deployed files; sync makes deployed output match the current manifests. list syncs the relevant cache and compares its contents against active manifests, reporting status via mode glyphs rather than inspecting generated files.
Sync Reconciliation¶
sync_all_modes() reconciles every initialized mode. For each one, sync_manifest_to_directory() clears managed output and replays manifest entries through copy_entry_to_target(), which routes by entity type.
graph TD
classDef action fill:#1e88e5,fill-opacity:0.16,stroke:#1e88e5,stroke-width:1.5px;
classDef decision fill:#f57c00,fill-opacity:0.16,stroke:#f57c00,stroke-width:1.5px;
classDef output fill:#2e7d32,fill-opacity:0.16,stroke:#2e7d32,stroke-width:1.5px;
Start["sync_all_modes()"]:::action --> Conflicts["resolve_conflicts()"]:::action
Conflicts --> Mode["For each active mode"]:::action
Mode --> Clear["Clear managed output"]:::action
Clear --> Entry["For each manifest entry"]:::action
Entry --> Kind{"Entity type?"}:::decision
Kind -->|"*.mdc file"| Rule["Rules target"]:::output
Kind -->|"*.md file"| Command["Commands target"]:::output
Kind -->|"directory with SKILL.md"| Skill["Skills target"]:::output
Kind -->|"ruleset directory"| Ruleset["Walk children"]:::action
Ruleset --> Kind
Two cross-cutting properties of this flow are easy to miss:
- Commit wins on conflict. When the same deployed filename would land from two modes, sync keeps the committed copy and drops the local one. User-facing rules: Constraints.
- Symlinks are followed but sandboxed. Targets must resolve inside the source cache; out-of-repository symlinks are skipped. Detail: Rulesets §Symlink Security.
Development Boundaries¶
The most important implementation boundary is between desired state (manifests) and generated state (Cursor output). When changing behavior, look first at the manifest mutation path and the sync path, not at ad hoc edits in generated directories.
When adding a new entity type or changing deployment behavior, expect to touch all of these areas:
- Detection and routing helpers.
listdisplay logic.addandremovemanifest behavior.copy_entry_to_target()deployment behavior.- Conflict resolution and sync cleanup if filenames can overlap across modes.
- Unit or integration tests, depending on whether the behavior is pure helper logic or filesystem/git behavior. See Testing.