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
2 changes: 1 addition & 1 deletion .claude/rules/wiki/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ paths:
- "src/cli/**"
---

Domain: cli. citty-based subcommand dispatch (serve/validate/export/index/version/update); `dict`/`graph`/`flow` are removal stubs; model-root discovery + interactive picker; port fallback + browser open on serve; self-update with streamed download progress + checksum verification
Domain: cli. `ignatius` binary dispatch via citty (serve/validate/index/export/approve/update); `dict`/`graph`/`flow` are removal stubs; model-root discovery + interactive `pickModel`; port fallback + browser open on serve; self-update with checksum verification

Map:
- docs/wiki/cli.md
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/wiki/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ paths:
- "docs/glossary.md"
---

Domain: docs. Design docs, user guides, research notes, and implementation-contract specs — 81 markdown files plus `docs/glossary.md` across `docs/design/`, `docs/guides/`, `docs/research/`, `docs/spec/`
Domain: docs. Design docs, user guides, research notes, and implementation-contract specs plus `docs/glossary.md` across `docs/design/`, `docs/guides/`, `docs/research/`, `docs/spec/`; model change review is in the `model-change-review` design/spec and the `change-review` guide

Map:
- docs/wiki/docs.md
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/wiki/flow-view.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ paths:
- "src/flow-view/**"
---

Domain: flow-view. ELK-driven DFD layout (5-band partitioning, orthogonal edge routing) with a stack-node model for per-process/connected views and three collapse levels (stores/clusters/groups); `flow-nav.ts` resolves exact diagram paths for the new flow index + breadcrumb level menus (`FlowIndex.tsx`/`LevelMenu.tsx`, replacing the old standalone nav card); pure coord helpers for polyline rendering; SVG renderer consumes ELK positions + edgeRoutes + search-token dimming and gates hover transitions through the frontend domain's hover-intent/animation-limit helpers
Domain: flow-view. ELK-driven DFD layout (band partitioning, orthogonal edge routing), stack-node model and collapse levels (stores/clusters/groups); SVG renderer with change-review glows; `flow-nav.ts` path resolution for the flow index and breadcrumb level menus, which show change marks (pill glow, pulsing or static `ChangeDot`, index change summary)

Map:
- docs/wiki/flow-view.md
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/wiki/flows.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ paths:
- "src/flows/**"
---

Domain: flows. SSADM data flow diagrams: `parseFlows` (recursive sub-DFDs + canonical Yourdon leveling via `deriveLevels`, now also reading a folder's own `description:` off `index.md`), `flow-clusters.ts` `cluster:` token expansion from `clusters/<slug>.md` author files, `validateFlows` (17 `flow.*` rules), `buildFlowLayoutKeys`, usage indexing; role-split node model
Domain: flows. SSADM data flow diagrams: `parseFlows` (recursive sub-DFDs + canonical Yourdon leveling via `deriveLevels`, reading a folder's own `description:` off `index.md`), `flow-clusters.ts` `cluster:` token expansion from `clusters/<slug>.md` author files, `validateFlows` (`flow.*` rules), `buildFlowLayoutKeys`, usage indexing; role-split node model

Map:
- docs/wiki/flows.md
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/wiki/frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ paths:
- "src/app/**"
---

Domain: frontend. React 19 unified SPA (Graph/Dictionary/Flows views); shell (`App.tsx`) owns state + composition; `logic/motion.ts` centralizes hover-intent debouncing and a per-view animation-element-limit; `flowview=`/`collapse=` hash params drive the flow view mode and collapse level; new `i` shortcut opens the flow index; `StackDialog`/`EdgeContractDialog` cover stack and edge-contract detail; views own cy/SVG lifecycle; components/logic/hooks/dom layered underneath
Domain: frontend. React 19 unified SPA (Graph/Dictionary/Flows views); shell (`App.tsx`) owns state + composition; change-review overlay (`ChangesPanel`, `ChangeBadge`/`ChangeDot`, `logic/change-marks.ts`) marks graph, Dictionary, flow nodes, flow index and level-menu rows, with removed items in warning red; modals stack above the global findings banner; `flowview=`/`collapse=` hash params; views own cy/SVG lifecycle

Map:
- docs/wiki/frontend.md
Expand Down
7 changes: 6 additions & 1 deletion .claude/rules/wiki/parser.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,27 @@ paths:
- "src/model/parse.ts"
- "src/model/wikilink.ts"
- "src/model/model-index.ts"
- "src/model/change-review.ts"
- "src/model/change-store.ts"
---

Domain: parser. `ignatius.yml` config loading → ParseResult: {model, globalErrors}; nodes, edges, cardinality + classification derivation; wiki-link inline rule + two-pass body rendering; `ModelMeta.flowView` (`flow_view:`/`adjacency_stacks`); `buildModelIndex` — 13 O(1) lookup maps built once per Model
Domain: parser. `ignatius.yml` config loading → ParseResult: {model, globalErrors}; nodes, edges, cardinality + classification derivation; wiki-link inline rule + two-pass body rendering (`linkStateNeutral`); `buildModelIndex` lookup maps; change review: `change-review.ts` diffs model + flows against the approved baseline kept by `change-store.ts` and cross-checks agent change notes

Map:
- docs/wiki/parser.md
Contracts:
- docs/spec/bidirectional-predicates.md
- docs/spec/derive-classification.md
- docs/spec/folder-model.md
- docs/spec/model-change-review.md
- docs/spec/wiki-entity-links.md
Designs:
- docs/design/bidirectional-predicates.md
- docs/design/folder-model.md
- docs/design/model-change-review.md
- docs/design/wiki-entity-links.md
Guides:
- docs/guides/change-review.md
- docs/guides/folder-format.md
- docs/guides/predicates.md

Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/wiki/scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ paths:
- "scripts/**"
---

Domain: scripts. Build helpers: stable-names.ts, convert-yaml-to-md.ts; perf/diagnostic tooling: probe.ts, screenshot.ts, gen-synthetic-model.ts, perf-harness.ts
Domain: scripts. Build helpers: stable-names.ts, convert-yaml-to-md.ts; test prelude clear-review-state.ts (removes `.ignatius/` review state from demo + fixture models); perf/diagnostic tooling: probe.ts, screenshot.ts, gen-synthetic-model.ts, perf-harness.ts

Map:
- docs/wiki/scripts.md
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/wiki/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ paths:
- "src/server/**"
---

Domain: server. Bun.serve with `/api/model` + `/api/flow` (now includes `clusters`) + `/events` SSE + fs.watch live-reload; `/dict` and `/flow` redirect to unified SPA hash routes; `/flow-dict` redirects to `/#view=dict`
Domain: server. Bun.serve with `/api/model` (carries the change-review `diff`), `POST /api/approve`, `/api/flow` (returns `clusters`), `/events` SSE live-reload driven by fs.watch plus a `baseline.json` stat poll; `/dict`, `/flow`, `/flow-dict` redirect to SPA hash routes

Map:
- docs/wiki/server.md
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/wiki/skill.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ paths:
- "skills/ignatius-modeling/**"
---

Domain: skill. Project-scoped Claude Code skill: Q&A-driven entity/model/DFD authoring, convention-aware, writes files + verifies with `ignatius validate`; a flow's own `description:` is now authored to `flows/<flow>/index.md` (Step F6a)
Domain: skill. Project-scoped Claude Code skill: Q&A-driven entity/model/DFD authoring, convention-aware, writes files + verifies with `ignatius validate`; ends every edit session with a `.ignatius/changes/<slug>.md` change note (`references/change-notes.md`) and never approves its own edits

Map:
- docs/wiki/skill.md
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/wiki/validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ paths:
- "src/model/validate.ts"
---

Domain: validate. Pure model validator: 38 RuleIds across 8 prefixes (parse/config/entity/body/edge/cluster/index/flow), two severity tiers (A=warn, B=omit); `flow.*` now 17 ids including five `flow.cluster_*` DFD-store-cluster rules; `validateIndex` reuses `buildRouters` to detect router drift
Domain: validate. Pure model validator: RuleIds across parse/config/entity/body/edge/cluster/index/flow prefixes, two severity tiers (A=warn, B=omit); `flow.cluster_*` DFD-store-cluster rules; `validateIndex` reuses `buildRouters` to detect router drift

Map:
- docs/wiki/validate.md
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ Edit any file in the folder and the graph reloads in the browser without a refre
| Guide | What it covers |
|---|---|
| [Getting started](docs/guides/getting-started.md) | Install, build from source, and serve your first model |
| [Commands](docs/guides/commands.md) | `serve`, `export`, `validate`, `index`, and model discovery |
| [Commands](docs/guides/commands.md) | `serve`, `export`, `validate`, `index`, `approve`, and model discovery |
| [Change review](docs/guides/change-review.md) | What changed since the last approval, change notes, and `approve` |
| [The folder format](docs/guides/folder-format.md) | `ignatius.yml`, entity files, columns, relationships, groups, generated routers |
| [What gets derived](docs/guides/derivation.md) | Cardinality, classification, and subtype clusters |
| [Bidirectional predicates](docs/guides/predicates.md) | Forward and reverse edge labels with hover-swap |
Expand Down
81 changes: 81 additions & 0 deletions docs/design/model-change-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Design: Model change review


## Problem


An AI agent edits a model by writing entity and flow markdown files directly. When the user opens `ignatius serve` afterwards, the graph renders the new state with nothing marking what the agent added, removed, or changed. The user has no way to review the edit visually before accepting it.


## Concepts


| Term | Meaning |
|------|---------|
| Baseline | The parsed model and flows at the last approval, stored as `.ignatius/baseline.json` next to `ignatius.yml`. |
| Change item | One semantic difference between the baseline and the current parse: an entity, column, relationship, body, or flow node that was added, removed, or changed. |
| Change note | A markdown file the agent writes to `.ignatius/changes/`. Frontmatter names the entities, columns, diagrams, and flow nodes it touched; the body explains why. |
| Approve | Moves the baseline to the current state and deletes the change notes. |


## Approach


Hybrid: ignatius computes the diff deterministically, and the agent's change notes explain it. Each source checks the other.

```mermaid
flowchart TD
B[baseline.json] --> D[diffSnapshots]
C[current parse] --> D
D --> X[crossCheck]
N[changes/*.md] --> X
X --> R["/api/model diff"]
R --> G[Graph / Dictionary / Flow highlights]
R --> P[Changes panel]
```

Cross-check outcomes:

| Diff | Note | Result |
|------|------|--------|
| changed | names it | highlighted, explanation shown |
| changed | silent | highlighted, flagged unexplained |
| unchanged | names it | flagged claimed but unchanged |

The diff alone shows what changed but never why. Notes alone are only as accurate as the agent that wrote them: an entity the agent forgot to list would never highlight. The two together surface both failure modes during approval.


## Business rules


- The baseline is a snapshot ignatius writes, not a git ref, so review works for a model folder outside any repository.
- `.ignatius/` is review state, never committed. A `.gitignore` next to `ignatius.yml` lists it. The modeling skill writes that file for every model it generates; ignatius adds the line when it creates `.ignatius/` and the line is missing.
- The diff runs on the parsed model, not file text. Reordering YAML keys or reformatting produces no change item.
- A body-only edit is its own kind (`doc`), so prose edits do not read as structural changes.
- Column granularity is required: a note covers a column change only when it names the column.
- Serve creates the baseline from the current state when none exists, so a first run highlights nothing. The modeling skill runs `approve` before its first write to a model with no baseline, so an agent's edits to a never-served model still show.


## Lifecycle


```mermaid
stateDiagram-v2
[*] --> Clean: serve creates baseline
[*] --> Clean: skill runs approve before first write
Clean --> Pending: agent edits files and writes notes
Pending --> Pending: more edits (live via SSE)
Pending --> Clean: ignatius approve / Approve button
Pending --> Claimed: user reverts files, note kept
Claimed --> Clean: user deletes or edits the note
Pending --> Clean: user reverts files (no note, or note deleted)
```


## Rejected approaches


- **Git diff against HEAD.** Fails for model folders outside a repository, and conflates "committed" with "approved".
- **Change notes only.** Cheaper, but the highlight trusts the agent; an omission is invisible.
- **Diff only.** Shows what changed but carries no explanation for the approval decision.
- **Committing notes.** They exist for one review cycle; git history already records what landed.
Loading
Loading