Skip to content

docs(event-storming): clear the Design-Level y-overlap and collapse the duplicate scheme - #1789

Merged
kyle-sexton merged 2 commits into
mainfrom
design/1555-dl-y-coordinate-spacing
Jul 30, 2026
Merged

docs(event-storming): clear the Design-Level y-overlap and collapse the duplicate scheme#1789
kyle-sexton merged 2 commits into
mainfrom
design/1555-dl-y-coordinate-spacing

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the owner-approved decision on melodic-software/medley#1555: widen Design-Level row spacing past the overlap threshold, keeping the single-flow model, then collapse the orphaned duplicate scheme into a reference to the corrected table. Both findings live in one file, plugins/event-storming/skills/simulation/reference/miro-integration.md.

Finding 1 — the Design-Level table overlapped itself. Actors (-200), Commands (-100) and Aggregates (0) sat in 100px gaps, under the ~199px threshold these layouts use.

Rows above the Aggregates baseline now sit 250px apart. The decision permits any gap ≥200px; I used 250 for two reasons rather than taking the minimum. This file's own Spacing summary already states Vertical (rows) | 250px, so 250 makes the table agree with the guidance printed below it. And the threshold is written as "~199px" — a 200px gap clears an approximate bound by one pixel, which is not margin. Aggregates stays the y=0 baseline. Rows below it were untouched as first pushed; review has since added a Policies row, which shifts the two bottom rows down by 250px — see Finding 3.

Finding 2 — the orphaned block was a third scheme, not a stale copy of either table. It restated Actors -250, Read Models -450, Hot Spots -250, alternatives +250, matching neither canonical table, and it opened with "Main flow (y=0 baseline): Commands, Events, Policies all sit on y=0" — true of the single-flow model it was written for, but not of Design-Level, where Aggregates holds y=0. So it was not merely duplicated, it was actively wrong for the phase it sat under.

Its y literals are gone. What it uniquely carried is kept: the flow reads left to right at 400px per item, and one flow step is a column sharing an x. The worked example now names table rows instead of restating their values, so the tables stay the only place y is written down — the same treatment #1473 / #219 gave the drifting literals.

Finding 3 — the Design-Level table had no Policies row (found in review). Raised as a
P2 by chatgpt-codex-connector against the worked example. agentic-simulation.md puts
policies on this board twice — :875 carries them over from Process Modeling, and :881
adds more in Step 3 — but the Design-Level table never gave them a row, so the example
borrowed Domain Events, whose Purpose column reads "Orange — outcomes" while a policy is
violet. Finding 2's new wording is what makes the omission load-bearing rather than
cosmetic: once the text says the tables are the only place y is written down, an element with
no row leaves an agent nothing correct to pick.

Pre-existing state was wrong differently — on main the example read Policy: x=800, y=0,
and y=0 in this phase is the Aggregates baseline. So the gap predates this PR, but it
lands on lines this PR rewrote under a rule this PR tightened, which makes it a fix rather
than a deferral.

Policies now sits at 1650, directly below the two event rows — a policy reacts to an
event, and the Process Modeling table already groups the two on its Event-Command-Policy
spine. That keeps Domain Events and Alternative outcomes adjacent and keeps internal
reactive logic above the BC Contracts (outbound) boundary row. It shifts What-if challenges 1700 → 1950 and BC Contracts (outbound) 2000 → 2250. Nothing
downstream restates these values — simulation-evaluation.md, iteration-workflow.md and
SKILL.md all reference phase rows by name, never by coordinate — so the shift is
contained to this one table.

Review also noted the worked example had dropped the Read Model that used to head its x=0
column. Restored, so the example again walks every row it touches.

Test plan

The issue asks for an x-aware geometric overlap check (two elements overlap only when their x-ranges intersect and |Δy| < ~199px). Every row in one phase's table shares the same x band — a flow step is a column — so x always intersects and the test reduces to adjacent |Δy| across the sorted rows.

Run against origin/main and against this branch:

Before — reproduces exactly the two overlaps the issue reported:

  ok:      Read Models <-> Actors |dy|=200px
  OVERLAP: Actors <-> Commands |dy|=100px
  OVERLAP: Commands <-> Aggregates |dy|=100px
  ok:      Aggregates <-> Business Rules |dy|=300px
RESULT: 2 overlap(s)          exit=1

After:

  ok:      BC Contracts (inbound) <-> Read Models |dy|=250px
  ok:      Read Models <-> Actors |dy|=250px
  ok:      Actors <-> Commands |dy|=250px
  ok:      Commands <-> Aggregates |dy|=250px
  ok:      Aggregates <-> Business Rules |dy|=300px
RESULT: no overlaps           exit=0

That the before run independently reproduces the issue's reported figures is what makes the after run meaningful — the check is measuring the right thing, not passing vacuously.

The other two phase tables were run through the same check to confirm this change did not disturb them: Big Picture — no overlaps; Process Modeling — no overlaps.

After Finding 3's row insert, the same adjacent-|dy| walk was re-run over the widened
Design-Level table, since the shift has to keep clearing the minimum. This run also flags
gaps that clear the ~199px overlap bound but fall under the file's own stated 250px minimum,
which the earlier pass did not distinguish:

=== Design-Level Y-Coordinate Table (11 rows) ===
  ok             BC Contracts (inbound) <-> Read Models |dy|=250px
  ok             Read Models <-> Actors |dy|=250px
  ok             Actors <-> Commands |dy|=250px
  ok             Commands <-> Aggregates |dy|=250px
  ok             Aggregates <-> Business Rules |dy|=300px
  ok             Business Rules <-> Domain Events |dy|=800px
  ok             Domain Events <-> Alternative outcomes |dy|=300px
  ok             Alternative outcomes <-> Policies |dy|=250px
  ok             Policies <-> What-if challenges |dy|=300px
  ok             What-if challenges <-> BC Contracts (outbound) |dy|=300px

The walk reads each row's declared y, so the Business Rules row shows an 800px delta to
Domain Events; that row stacks at 300/550/800, so the real clearance from the bottom of the
stack is 300px. Every other pair is its literal gap.

Big Picture stays clean on that stricter check. Process Modeling does not — its three
rows above the baseline are 200px apart, clear of the ~199px overlap bound but 50px short of
the stated minimum. That is pre-existing, reproduces on main, and is out of scope here;
filed as melodic-software/medley#1689 with the mechanical output.

markdownlint-cli2 on the edited file: 0 errors.

Not covered

No Miro render was performed — the verification is geometric, as the issue specifies. A to-scale visual confirmation is still worth doing by whoever next opens one of these boards, since only a render exercises sticky dimensions rather than centre coordinates.

Related

Refs melodic-software/medley#1555

🤖 Generated with Claude Code

https://claude.ai/code/session_01RhS3T7ShwJgKTrvk2Mvd3C

Fixes melodic-software/medley#1555

…he duplicate scheme

The Design-Level Y-Coordinate Table packed Actors (-200), Commands (-100) and
Aggregates (0) into 100px gaps, under the ~199px threshold these layouts use.
An x-aware check confirms both overlaps: rows in one phase table share an x
band, so x always intersects and the test reduces to adjacent |dy|.

Rows above the Aggregates baseline now sit 250px apart rather than the minimum
that clears the threshold — 250px is what this file's own Spacing summary
already states for vertical rows, and 200px would clear a "~199px" threshold by
a single pixel. Aggregates stays the y=0 baseline and nothing below it moves.

The orphaned block after the table restated a third coordinate scheme (Actors
-250, Read Models -450, Hot Spots -250, alternatives +250) matching neither
canonical table, and described Commands sitting on the y=0 baseline — true of
the single-flow model it was written for, not of Design-Level, where Aggregates
holds y=0. Its y literals are gone. What it uniquely carried survives: the flow
reads left to right at 400px per item, and a step is a column, so the example
now names table rows instead of restating their values.

Refs melodic-software/medley#1555

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RhS3T7ShwJgKTrvk2Mvd3C
@claude

claude Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 37s —— View job


PR Review

  • Gather context and read changed files
  • Review the diff for correctness and consistency
  • Check alignment with PR description and referenced issue
  • Post final review

Summary

Clean, well-scoped documentation fix. The two findings described in the PR body are both addressed correctly, and the approach (single source of truth for y-values, row-name references instead of inline literals) is consistent with the pattern established in #1473 / #219.


Finding 1 — y-value gaps: correct

The four rows above the Aggregates baseline are each spaced 250 px apart:

Pair Old gap New gap
Commands → Aggregates 100 px ❌ 250 px ✓
Actors → Commands 100 px ❌ 250 px ✓
Read Models → Actors 200 px (borderline) 250 px ✓
BC Contracts → Read Models 200 px (borderline) 250 px ✓

The new values agree with the Spacing summary at line 222 (Vertical (rows) | 250px) and clear the ~199 px sticky-height threshold with a meaningful buffer. Rows below the baseline are untouched, which is correct.


Finding 2 — orphaned block: correctly removed

The removed block opened with "Commands, Events, Policies all sit on y=0" — true of the single-flow model, not Design-Level, where Aggregates holds y=0. Restating Actors at -250 and Read Models at -450 also contradicted the table it sat directly below. The replacement correctly:

  • Defers all y values to the table above (no inline literals to drift).
  • Preserves the unique non-y content: 400 px per step, column-per-step layout.
  • Uses row names in the worked example so the example stays correct even if table values change later.

One minor observation: the old worked example included a Read Model at the head of the x=0 column; the new one starts at Actor. The example is illustrative rather than exhaustive, so this is a simplification not a loss, but worth being aware of if the example is ever expanded.


Pre-existing gap worth a follow-up (not introduced here)

Line 122 states "250px minimum between ALL adjacent rows", but the Process Modeling table (lines 162–169) uses 200 px gaps above its baseline (External Systems → Read Models → Actors → Main Flow). That is right at the ~199 px sticky threshold. The PR doesn't touch Process Modeling and the PR body notes it passes the geometric check, but 200 px clearing a "~199 px" bound by one pixel is the same category of fragility this PR fixes in Design-Level. Worth a follow-up issue.


Verdict

Approve. The y-value changes are arithmetically correct, the Spacing summary is now internally consistent across Design-Level, and the orphaned block's removal eliminates an actively wrong description of the baseline. No blocking issues.

@claude

claude Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 43s —— View job


Security Review — PR #1789

  • Load tools
  • Gather context — read PR diff and changed file
  • Analyze for security issues
  • Post findings

Findings

No security issues found.

This PR makes two changes, both confined to the Design-Level Y-Coordinate Table section of plugins/event-storming/skills/simulation/reference/miro-integration.md:

  1. Coordinate value corrections — four y-values widened from 100 px gaps (-200, -100, -600, -400) to 250 px gaps (-500, -250, -1000, -750). These are pure numeric constants in a documentation table with no code-execution surface.

  2. Orphaned prose block removed — the deleted block restated y-coordinates narratively (incorrectly, per the PR description) and was replaced with prose that references the table above rather than duplicating values. The replacement block contains no URLs, no shell constructs, no template expressions, and no secrets.

Areas checked and found clean:

  • No injection surfaces (command, path, template) — the changed lines are static markdown text and numeric literals.
  • No secrets, tokens, or credentials introduced or exposed.
  • No authorization or access-control logic touched.
  • No GitHub Actions workflows modified.
  • No supply-chain risk — no new dependencies, action pins, or external URLs added.
  • No trust-boundary changes — the existing trust decision (reject remote Miro MCP, use local-stdio plugin instead) and its rationale at lines 15–20 are untouched.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7083f176f2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/event-storming/skills/simulation/reference/miro-integration.md Outdated
@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Classifying the two actionable items from your review individually. The verdict itself and Findings 1-2 need no action — they confirm the diff rather than contest it.

# Finding Classification Evidence Reacted
1 The old worked example opened its x=0 column with a Read Model; the new one starts at Actor VALID — fixing Taking this on the factual observation, not as a defect — you called it "a simplification not a loss" and that reading is fair. But Read Models is a real row in the Design-Level table (-750), the column-per-step example is the one place a reader sees a row used, and the fence is already being edited for the Policies row below, so restoring Read Model x=0 row: Read Models costs nothing and keeps the example exhaustive over the rows it walks. 👍
2 :122 states "250px minimum between ALL adjacent rows", but the Process Modeling table (:162-165) uses 200px gaps above its baseline VALID (defer) — filed as melodic-software/medley#1689 Reproduced mechanically rather than by eye, with an adjacent-|dy| check over all three phase tables at head 7083f176: Process Modeling reports UNDER-MINIMUM on External Systems <-> Read Models, Read Models <-> Actors, and Actors <-> Main Flow, all |dy|=200px. Big Picture and Design-Level both come back clean, so Process Modeling is the only table still out of step. Your framing is precise — 200px clears the ~199px overlap bound, so nothing overlaps and this PR's geometric check passed honestly, but it carries none of the 50px buffer the rule exists to provide. 👍

On the deferral, per the review discipline's provenance test: this reproduces on main and this PR touched only Design-Level rows, so it is not a regression this change introduced and deferral is available. medley#1689 carries your claim, the mechanical output above, and the file:line, and it frames the actual decision — widen the three rows to 250px (nothing downstream restates the values; consumers reference these rows by name) versus correct :122 if 200px is in fact acceptable.

Latency caveat, stated plainly: #1689 is filed work-class: scoped but status: needs-decision, so it sits in the human-gated queue rather than the autonomously-drainable one. Its latency is unbounded until someone makes that call — a weaker deferral than an agent-ready item, and worth knowing before this PR merges over it.

Follow-up with the commit SHA for item 1 to come.

The Design-Level Y-Coordinate Table never carried a Policies row, so the
worked example borrowed Domain Events — a row whose Purpose reads "Orange
— outcomes" while a policy is violet. Making the tables the sole home of
y values turned that omission load-bearing: an element with no row leaves
nothing correct to pick.

Policies sits at 1650, directly below the two event rows, since a policy
reacts to an event and the Process Modeling table already groups the two
on its Event-Command-Policy spine. What-if challenges and BC Contracts
(outbound) shift down 250px to keep every adjacent gap at or above the
minimum. Consumers reference these rows by name, never by coordinate, so
the shift stays inside this table.

Also restores the Read Model that headed the example's x=0 column, so the
example again walks every row it touches.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 3s —— View job


Security Review — PR #1789

  • Load tools
  • Read PR diff
  • Read changed file
  • Analyze for security issues
  • Post findings

Findings

No security issues found.

This PR's two commits (7083f17, 32d006d) both touch only plugins/event-storming/skills/simulation/reference/miro-integration.md, a markdown reference document. The net changes are:

  1. Y-coordinate values adjusted in the Design-Level Y-Coordinate Table — four rows above the Aggregates baseline widened from 100 px gaps to 250 px gaps; two rows below shifted to accommodate the new Policies row.
  2. Policies row added to the Design-Level table (y=1650, violet), with downstream rows shifted by 250 px.
  3. Orphaned prose block removed — a block that restated y-coordinates (incorrectly, for the wrong phase baseline) was replaced with prose that references the table by row name only.
  4. Worked example updated to reference row names instead of bare y-literals, and extended to include the new Policies row.

Areas checked and found clean:

  • Injection surfaces (command, path, template): None. The changed lines are static markdown text and numeric literals. No shell constructs, template expressions, or format strings.
  • Secrets / credentials / tokens: None introduced or exposed. The existing guidance (lines 39–42) that API tokens are stored via Claude Code's secure credential mechanism — never as a plain settings.json value — is untouched.
  • Authorization / access-control logic: None in scope; the file is reference documentation.
  • Trust boundary: The durable decision to reject the remote Miro MCP server (mcp.miro.com, OAuth 2.1) in favour of the local-stdio plugin is at lines 15–20 and is not touched by either commit.
  • GitHub Actions / CI: No workflow files modified.
  • Supply-chain risk: No new external URLs, action pins, or dependencies. The Sources section (lines 274–279) is pre-existing and unchanged.
  • Dangerous MCP patterns: No MCP server configuration changes. The tool-namespace guidance (lines 23–29) and setup instructions (lines 32–45) are untouched.

@claude

claude Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 2m 19s —— View job


PR Review — follow-up commits

  • Load tools
  • Read current diff (all commits on this branch vs origin/main)
  • Verify Policies row addition and spacing math
  • Verify worked example restored Read Models
  • Verify no new inline y-literals in prose
  • Post final review

Review of commit 32d006d

This commit addresses both items kyle-sexton flagged in the classification response. Both are handled correctly.


Item 1 — Policies row: correct

The row is placed at y=1650, directly below Alternative outcomes (1400). Full gap audit of the Design-Level table as it now stands:

Pair Gap
BC Contracts (inbound, −1000) → Read Models (−750) 250 px ✓
Read Models (−750) → Actors (−500) 250 px ✓
Actors (−500) → Commands (−250) 250 px ✓
Commands (−250) → Aggregates (0) 250 px ✓
Aggregates (0) → Business Rules (300) 300 px ✓
Business Rules (300) → Domain Events (1100) 800 px ✓ (stacking headroom)
Domain Events (1100) → Alternative outcomes (1400) 300 px ✓
Alternative outcomes (1400) → Policies (1650) 250 px ✓
Policies (1650) → What-if challenges (1950) 300 px ✓
What-if challenges (1950) → BC Contracts (outbound, 2250) 300 px ✓

Every adjacent gap meets the 250 px minimum. The two shifted rows (What-if challenges 1700→1950, BC Contracts (outbound) 2000→2250) each move down exactly 250 px, preserving their original 300 px gaps.

The Purpose description — Violet — reactive \Whenever X, do Y`` — is accurate and consistent with how Policies is described elsewhere in the file.


Item 2 — Worked example: correct

Two corrections in the code fence at lines 197–205:

  1. Read Model x=0 row: Read Models restored at the head of the column — the element is back and its row reference is valid.
  2. Policy x=800 row: Policies — the row pointer is now correct. The previous row: Domain Events pointed to an orange-outcome row for a violet reactive element.

Every element in the example now references a row that exists in the table above it. No inline y-literals appear anywhere in the prose.


Consistency check — legend sizing note

Line 214 reads Design-Level legend (8+ types): 500w x 1800h. The 8+ is a floor on element-type count, not a row count, and Policies was already a valid element type in Design-Level boards — it just lacked a y-coordinate row. The legend note does not need updating.


Verdict

Approve. The two items from the classification comment are fully resolved. The table is now arithmetically consistent from top to bottom, the worked example is exhaustive over every row it walks, and the single-source invariant (tables are the only place y values are written) is upheld. No blocking issues.

@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Follow-up on item 1 (Read Model dropped from the worked example) — fixed in
32d006dc5184b3e4c1ef291e3950fe0e737e83d7:

+ Read Model       x=0       row: Read Models
  Actor            x=0       row: Actors
  Command          x=0       row: Commands

The same commit addresses the chatgpt-codex-connector P2 in the adjacent thread by adding a
Policies row at 1650, which shifts What-if challenges to 1950 and BC Contracts (outbound)
to 2250. Your Finding 2 note that the example "starts at Actor" and the codex finding turned out
to share a cause: the rewritten example had drifted from the set of rows the table actually
defines, in one case dropping a row and in the other borrowing a wrong one.

Item 2 (Process Modeling 200px gaps) stays deferred to melodic-software/medley#1689, filed
work-class: scoped / status: needs-decision. Restating the caveat rather than pointing back
at it: that label puts it in the human-gated queue, so its latency is unbounded until an owner
picks between widening the three rows and correcting the :122 rule text. Nothing in this PR
depends on that call.

Verification re-run after the change: adjacent-|dy| walk clean across Big Picture and
Design-Level (Process Modeling still reports the three 200px gaps, as expected and as filed);
markdownlint-cli2 0 errors.

@kyle-sexton
kyle-sexton merged commit 5f0b454 into main Jul 30, 2026
33 checks passed
@kyle-sexton
kyle-sexton deleted the design/1555-dl-y-coordinate-spacing branch July 30, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant