Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ curl -fsSL https://raw.githubusercontent.com/noormdev/ignatius/main/install.sh |

It installs to `/usr/local/bin` when writable, otherwise `$HOME/.local/bin`. Override with `IGNATIUS_INSTALL_DIR`, or pin a version with `IGNATIUS_VERSION=v0.2.0`. Windows users download `ignatius-windows-x64.exe` from the releases page. Prefer to build from source? See [Getting started](docs/guides/getting-started.md).

To author models from Claude Code with guided Q&A, install the `noorm-modeling` skill ([the modeling skill](docs/guides/modeling-skill.md)):
To author models from Claude Code with guided Q&A, install the `ignatius-modeling` skill ([the modeling skill](docs/guides/modeling-skill.md)):

```bash
npx skills add https://github.com/noormdev/ignatius --skill noorm-modeling
npx skills add https://github.com/noormdev/ignatius --skill ignatius-modeling
```

Add `-g` to install it globally for every project instead of just the current one.
Expand Down Expand Up @@ -62,7 +62,7 @@ Edit any file in the folder and the graph reloads in the browser without a refre
| [Process flows](docs/guides/flows.md) | Data flow diagrams: processes, externals, stores, sub-DFDs |
| [Validation and findings](docs/guides/validation.md) | The linter, severity tiers, and where findings surface |
| [Themes and branding](docs/guides/themes-and-branding.md) | Color palettes, the light/dark toggle, logo and copyright |
| [The modeling skill](docs/guides/modeling-skill.md) | `/noorm-modeling` Q&A authoring in Claude Code |
| [The modeling skill](docs/guides/modeling-skill.md) | `/ignatius-modeling` Q&A authoring in Claude Code |
| [Building from source](docs/guides/building-from-source.md) | Build stages, project layout, and tests |

The [glossary](docs/glossary.md) defines the shared vocabulary — DG, DD, DFD, data entity, data store, external entity — used across the app, the docs, and the code.
Expand Down
4 changes: 2 additions & 2 deletions docs/design/dfd-nesting-depth.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ number (e.g. `4.1`) and never receives the `N.` prefix → renders `4.1` instead
`5.4.1`. (Even if it were reached, taking only the last segment would collapse
`5.4.1` → `5.1`.) The defect is entirely in `deriveLevels`; the parser is correct.

A second, separate gap: `skills/noorm-modeling/references/dfd-authoring.md` Step F8
A second, separate gap: `skills/ignatius-modeling/references/dfd-authoring.md` Step F8
+ the folder-layout sketch show a single sub-DFD level and never state that a
child process can itself be decomposed — the skill's implicit one-level cap.

Expand All @@ -31,7 +31,7 @@ child process can itself be decomposed — the skill's implicit one-level cap.
- **Goals**
- Dotted process numbers preserve the full ancestor chain at any depth: `N.a`,
`N.a.b`, `N.a.b.c`, …
- The `noorm-modeling` skill's `flow` mode authors/organizes nested DFDs down
- The `ignatius-modeling` skill's `flow` mode authors/organizes nested DFDs down
arbitrarily many layers (F8 is explicitly recursive).
- **Non-goals**
- Parser changes — recursion and relative numbering are already correct.
Expand Down
2 changes: 1 addition & 1 deletion docs/design/example-instance-tables.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ New rule `entity.example_unknown_column` — Class A, severity `warning`, `liveO

E5b runs every time an entity is created. It is not skippable — examples are part of modeling, not a polish step. Verification loop at E8 also checks that the generated examples parse cleanly (no `example_unknown_column` warnings in `ignatius dict` output).

`docs/design/noorm-modeling-skill.md` mermaid updates to show E5b between E5 (columns) and E6 (description). `docs/spec/noorm-modeling-skill.md` gets a change log entry recording the new step.
`docs/design/ignatius-modeling-skill.md` mermaid updates to show E5b between E5 (columns) and E6 (description). `docs/spec/ignatius-modeling-skill.md` gets a change log entry recording the new step.

## Resolved questions

Expand Down
160 changes: 160 additions & 0 deletions docs/design/ignatius-modeling-skill.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Ignatius modeling skill


## Problem

Authoring an ignatius entity file today means:

1. Hand-write the YAML frontmatter without IDE help (no schema, no completion).
2. Remember the IDEF1X classification rules (independent vs dependent vs subtype — including the FK-in-PK = dependent rule that even seasoned users get wrong).
3. Know that group color, sort_key, and theme must live in `groups/*.md` and `ignatius.yml`, not on the entity itself.
4. Run `ignatius dict` afterwards to discover mistakes — by which point the lint surface is reactive, not preventive.

The result: every new contributor's first entity is a half-broken file that produces lint warnings on first run. Reviewers spend cycles on mechanical issues. The skill is the antidote — a guided authoring loop that produces a properly-formed file the first time and verifies it by invoking the CLI.


## Goals / Non-goals

- **Goals**
- One skill (`/ignatius-modeling`) with two modes selected by a positional arg:
- **`entity`** — author a single entity .md file given an existing `models/` root.
- **`model`** — bootstrap a complete `models/` skeleton (`groups/`, a single `ignatius.yml` carrying optional theme + branding, one or two reference entities).
- The skill knows the IDEF1X rules — it asks the right questions in the right order so the resulting file satisfies the linter on first run.
- After writing, the skill runs `ignatius validate <models>` and reports any lint findings. If findings appear, the skill prompts the user to fix them iteratively.
- The skill is invoked via the standard Claude Code skill mechanism: `/ignatius-modeling entity` or `/ignatius-modeling model`. Bare `/ignatius-modeling` asks the user to pick.
- Skill output: real file(s) on disk, staged but not committed.

- **Non-goals**
- The skill is NOT the linter. It depends on the linter (`schema-lint-and-error-ux` spec) to verify output.
- No autonomous bulk-create (skill won't loop through "add 20 entities from a CSV" — single-entity or single-model invocations only).
- No model migration (the older YAML format → current markdown format). `scripts/convert-yaml-to-md.ts` covers that case.
- No reverse-engineering of an existing entity (.md file → form to edit). Could come later.


## Sub-modes


### `entity` flow

```mermaid
flowchart TD
Start[User: /ignatius-modeling entity] --> Q1{Models dir specified?}
Q1 -->|no| AskDir[Ask for models/ path]
Q1 -->|yes| Parse[parseModels existing]
AskDir --> Parse
Parse --> Q2[Ask: entity id]
Q2 --> Q3[Ask: group]
Q3 --> Q4[Pick convention<br/>key-inherited or orm-oriented<br/>inherit from model if known]
Q4 --> Q5[Ask: PK columns<br/>guidance per convention]
Q5 --> Q6{Has parent relationships?}
Q6 -->|yes| Q7[Ask: each parent, target + on mapping]
Q6 -->|no| Q8[Skip relationships]
Q7 --> Check{Convention contradicted?}
Check -->|key-inherited + PK omits parent PK| Resolve[Prompt: include parent PK<br/>or switch convention]
Check -->|orm-oriented + FK in PK| Resolve
Check -->|consistent| Q8
Resolve --> Q5
Q8 --> Q9[Ask: additional columns]
Q9 --> Q9b[Ask: example rows?<br/>optional — goes in examples: frontmatter]
Q9b --> Q10[Ask: reference table?<br/>default no]
Q10 --> Q11[Ask: optional body description]
Q11 --> Write[Write the .md file]
Write --> Lint[Run ignatius dict + lint]
Lint --> Report{Any findings?}
Report -->|no| Success
Report -->|yes| Loop[Surface findings to user,<br/>offer to edit]
Loop --> Q2
```

Key behavior: the skill uses the user's earlier answers to *prevent* lint violations rather than just catching them. The classification (`Independent`, `Dependent`, `Associative`, `Subtype`, `Classifier`) is **derived by the parser** from PK/FK structure — the skill does not ask. Instead the skill catches **convention contradictions** in the question flow: if the user picked `key-inherited` but declared a PK that omits parent PK columns, or picked `orm-oriented` but put an FK in the PK, the skill prompts to either fix the keys or switch the convention.

### `model` flow

```mermaid
flowchart TD
Start[User: /ignatius-modeling model] --> Q1[Ask: target dir<br/>default ./models]
Q1 --> Q2[Ask: model name<br/>for ignatius.yml name + branding title]
Q2 --> Q3[Pick default convention<br/>key-inherited or orm-oriented]
Q3 --> Q4[Ask: theme<br/>default Noorm / custom?]
Q4 --> Q5[Ask: group names + colors<br/>at least 1]
Q5 --> Q6[Optional: bootstrap one<br/>reference entity to demo]
Q6 --> Write[Write groups/*.md,<br/>ignatius.yml with theme + branding,<br/>optionally one entity]
Write --> Lint[Run ignatius dict on new dir]
Lint --> Success
```

The skeleton is intentionally minimal — no inflated example data. One group, optionally one entity, ready to grow. The default convention is recorded as a comment in `ignatius.yml` so subsequent `entity` invocations against this root inherit it.


## Invocation

- Skill file lives in this repo so it ships with the project. Path: `skills/ignatius-modeling/SKILL.md` (project-scoped skill).
- Name: `/ignatius-modeling`. One skill, one file. Mode selected by positional arg: `entity` or `model`.
- Bare `/ignatius-modeling` (no arg) prompts the user to pick which mode. Unknown args fall to the same prompt.
- Invokable from anywhere; if not inside an ignatius `models/`-bearing project the skill asks for paths.


## Knowledge encoded in the skill

The single `SKILL.md` must encode:

- The exact required + optional fields for an entity .md file (id, group, pk, columns, relationships, alternateKeys, reference, body). **No `classification`, no per-edge `identifying`** — both are derived by the parser.
- The **authoring convention axis** (`key-inherited` vs `orm-oriented`) and how key placement differs:
- `key-inherited`: parent PK propagates into child composite PK; FK columns live in the child PK.
- `orm-oriented`: each entity has a single surrogate `id` PK; FK columns sit outside the PK as plain columns.
- The convention-contradiction detection rules:
- `key-inherited` + PK that omits parent PK columns → prompt to include them or switch convention.
- `orm-oriented` + FK column in the PK → prompt to drop it or switch convention.
- The IDEF1X *intuition* behind the conventions (so the user understands what derivation will produce), but **never as a question the user has to answer**. Classification follows from key shape.
- The `groups/*.md` schema (label, color, optional sort_key, optional desc).
- The `ignatius.yml` schema (`name`, `version`, `description`, `updated`, `theme:`, `branding:` blocks — single config file per `docs/spec/ignatius-project-config.md`).
- Pointers to the linter rule catalog so the skill's questions map 1:1 with what the linter would flag.

These are kept in sync with the canonical sources — `docs/spec/schema-lint-and-error-ux.md`, `docs/spec/derive-classification.md`, `docs/spec/ignatius-project-config.md`, and `docs/design/markdown-driven-erd.md`. If the linter rules change, the skill author updates the skill: explicit, not automatic.

The citation lives HERE, not in the skill. `npx skills add … --skill ignatius-modeling` copies only `skills/ignatius-modeling/` into the user's `.claude/skills/`, so a repo-relative path written into `SKILL.md` or any `references/*.md` is a dead link on every machine but this one — and Claude will try to Read it. Nothing shipped in the skill may cite `docs/`, `src/`, `spec/`, or any other repo path. A pointer with genuine user value goes in as a full `https://github.com/noormdev/ignatius/blob/main/…` URL; a maintainer-only pointer stays in this document.


## Verification loop

After writing files, the skill runs `ignatius validate <dir>` (the validate-only quality gate — no HTML output) and parses the CLI's stderr lint output (the format defined by `schema-lint-and-error-ux`). For each finding:

- The skill reports the category + message + fix hint to the user.
- The skill offers to revise: "Update the file?" — if yes, the skill walks the relevant question subset again with the original answers prefilled, writes the file, re-runs.
- Loop bounded to 5 attempts (defensive against infinite cycles from misbehaving CLI).

The verification step depends on the linter's structured stderr — `src/validate.ts:formatFindingsForStderr` is live and emits `<sev> <ruleId> <location> <message>` one line per finding, called from `src/cli.ts` after `parseModels` + `validateModel`. The skill parses that format directly; no soft-verify gate remains.


## Open questions

- **Skill auto-stage?** Should the skill `git add` the new file(s)? Likely no — leave staging to the user. They might want to iterate before committing.
- **Body markdown content** — should the skill ask for a short description or leave the body blank? Probably ask for an optional one-sentence summary; longer prose is better written outside a Q&A flow.


## Approaches considered and rejected

| Rejected | Why |
|----------|-----|
| Two separate skills (`/new-entity` + `/new-model`) | User picked "separate sub-modes" — one skill, two args — in the original clarify round. Splitting into two skill files contradicts that selection and doubles the surface for no benefit. |
| Hand-rolled CLI subcommand (`ignatius new entity`) | Skills are the right surface — interactive, in-IDE, in the same loop as everything else Claude Code touches. CLI sub-command duplicates that surface. |
| Skill that writes through a templating library (Mustache, EJS) | Overkill. Skills are markdown + LLM judgment; templates would add a dep without buying much. |
| Skill that bypasses the linter and trusts its own checks | Would diverge over time. Skill DEPENDS on the linter; doesn't reimplement it. |
| Skill that doesn't verify (just writes the file) | Fails the goal — the whole point is "lint-clean on first run". Verify is non-optional. |


## Change log


### 2026-06-17 — Folder model migration (#16): groups/ path and entity location

**What changed:** All references to the group definition directory updated from `_groups/` to `groups/`. The model bootstrap and entity authoring steps now write group definitions under `groups/` at the model root; entity files go under `data/<group>/`.

**Superseded:** Group definitions were described as living in `_groups/*.md`. Entity files were globbed from the model root without a `data/` container.


### 2026-08-11 — Rename skill to ignatius-modeling

**What changed:** The skill renamed `noorm-modeling` → `ignatius-modeling`; this design doc moved from `docs/design/noorm-modeling-skill.md`.

**Why:** The skill ships with and authors ignatius models; the name now matches the product instead of the noorm umbrella.
6 changes: 3 additions & 3 deletions docs/design/noorm-flow-discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

## Problem

The `noorm-modeling` skill authors ERD entities (`entity` mode) and bootstraps models (`model` mode). It has **no mode for authoring SSADM data flow diagrams** — the flows feature ships parsing, validation, and an in-app viewer, but a user writes flow markdown by hand against `docs/spec/process-flows.md`. Two distinct gaps:
The `ignatius-modeling` skill authors ERD entities (`entity` mode) and bootstraps models (`model` mode). It has **no mode for authoring SSADM data flow diagrams** — the flows feature ships parsing, validation, and an in-app viewer, but a user writes flow markdown by hand against `docs/spec/process-flows.md`. Two distinct gaps:

1. **No structured flow-authoring path.** A user who already knows their processes still hand-writes `process:`/`inputs:`/`outputs:`/`examples:` frontmatter, the `externals/` and `stores/` folder layout at the model root, and the `db:`/`kind:` store taxonomy — with no guide and no first-run verification.

Expand Down Expand Up @@ -146,7 +146,7 @@ Lives in `references/reverse-engineering.md`, routed to from `discover` when a s

| # | Approach | Pros | Cons |
|---|----------|------|------|
| A | Two new modes on `noorm-modeling` (`flow` + `discover`), reusing the SKILL.md + references scaffold | Single skill knows both ERD and flows, so `db:` resolution and discovery's entity-derivation stay coherent; matches existing two-mode structure | SKILL.md grows; four modes to route |
| A | Two new modes on `ignatius-modeling` (`flow` + `discover`), reusing the SKILL.md + references scaffold | Single skill knows both ERD and flows, so `db:` resolution and discovery's entity-derivation stay coherent; matches existing two-mode structure | SKILL.md grows; four modes to route |
| B | A separate `noorm-flows` skill | Smaller per-skill surface | Splits the model knowledge in two; discovery (which emits entities) would straddle both skills; `db:` store resolution needs the ERD anyway |
| C | New validator rules to enforce examples + context richness | Code-guaranteed | User explicitly rejected: LLMs remember; "be and maybe be" not a code problem; blocks half-authored flows from validating |
| D | Bake the store-kind taxonomy into the validator as an enum | Standardized in code | User chose skill-side menu; keeps the kind list a suggestion, not a hard contract |
Expand All @@ -156,7 +156,7 @@ Lives in `references/reverse-engineering.md`, routed to from `discover` when a s

**Approach A.** Discovery's defining move — deriving entities from processes (gate 4) and writing the ERD before the DFD — only works if one skill owns both entity and flow authoring. Splitting (B) would force discovery to straddle two skills. Code-side enforcement (C, D) was settled against with the user: the method enforces examples and richness; the existing `flow-validate.ts` rules are the backstop, unchanged.

Evidence: existing skill scaffold (`skills/noorm-modeling/SKILL.md` + `references/*.md`) already carries two modes and the core rules `flow` mode inherits verbatim (positive form, act-don't-suggest, infer-before-asking, derive-never-ask). The logical apparatus is modeled on `~/.claude/commands/pressure-test.md` lines 73–102 (three laws, four causes, sufficient reason) — translated to a generative posture, not cloned. Canonical rules and the existing ignatius adoption decisions live in `docs/research/ssadm-dfd-rules.md`.
Evidence: existing skill scaffold (`skills/ignatius-modeling/SKILL.md` + `references/*.md`) already carries two modes and the core rules `flow` mode inherits verbatim (positive form, act-don't-suggest, infer-before-asking, derive-never-ask). The logical apparatus is modeled on `~/.claude/commands/pressure-test.md` lines 73–102 (three laws, four causes, sufficient reason) — translated to a generative posture, not cloned. Canonical rules and the existing ignatius adoption decisions live in `docs/research/ssadm-dfd-rules.md`.


## Resolved decisions
Expand Down
Loading
Loading