You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+23-5Lines changed: 23 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -271,6 +271,27 @@ Spark runs two separate pipelines during compilation, in this order:
271
271
272
272
New transformers go under `transformers:`. New persisters go under `persisters:`.
273
273
274
+
## DSL shape changes
275
+
276
+
Whenever you add, rename, or remove a DSL entity or section in `Diffo.Provider.Extension`
277
+
(or any Spark extension in this project), run this checklist in order:
278
+
279
+
1.**Update `.formatter.exs`** — add new entity names to `spark_locals_without_parens` with
280
+
each supported arity. Without this, `mix format` will add unwanted parentheses to every
281
+
DSL call site.
282
+
283
+
2.**Run `mix format`** — apply formatting across the codebase and verify the output looks
284
+
correct. Run `mix format --check-formatted` to confirm nothing was missed.
285
+
286
+
3.**Run `mix spark.cheat_sheets`** — regenerates
287
+
`documentation/dsls/DSL-Diffo.Provider.Extension.md`. This file is Spark-generated;
288
+
never edit it by hand. Commit the regenerated file alongside the DSL change.
289
+
290
+
4.**Run `mix test`** — confirm no regressions.
291
+
292
+
Do not skip step 1 even for a "small" entity addition — the formatter will silently reformat
293
+
every call site in CI and produce noisy diffs in future PRs.
294
+
274
295
## Raising upstream bugs
275
296
276
297
When a bug is found in a dependency (e.g. AshNeo4j, Bolty), raise a GitHub issue on that
@@ -309,11 +330,8 @@ not. Add any useful hypotheses as a follow-up comment on the issue, then leave i
309
330
- Using module names (e.g. `MyApp.CardInstance`) as role values in `relationships do` — roles are atoms like `:provides`, not module references.
310
331
- Forgetting that `relationships do` omitted means `:none` for both source and target — any update action with `argument :relationships, {:array, :struct}` will fail unless the resource declares permissions.
311
332
- Thinking the Assigner requires `relationships do` permissions — it does not. The Assigner writes `DefinedSimpleRelationship` records directly via the Provider domain; `ValidateRelationshipPermitted` only runs on actions that carry `argument :relationships, {:array, :struct}`, which the Assigner's `assign_*` actions do not.
312
-
- Editing `documentation/dsls/DSL-Diffo.Provider.Extension.md` — it is Spark-generated;
313
-
run `mix spark.cheat_sheets` to regenerate it. Whenever you add, rename, or remove a DSL
314
-
entity or section, also check `.formatter.exs` — new entity names must be added to
315
-
`spark_locals_without_parens` (with each arity) so the Spark formatter omits parentheses.
316
-
Run `mix format` afterward to verify.
333
+
- Editing `documentation/dsls/DSL-Diffo.Provider.Extension.md` — it is Spark-generated.
334
+
See the **DSL shape changes** section above for the full checklist.
317
335
- Editing content between `<!-- usage-rules-start -->` markers in `CLAUDE.md` — that is
318
336
auto-generated by `mix usage_rules.sync`.
319
337
- Forgetting `Diffo.Provider.DomainFragment` on a scenario 3 domain — any domain whose
@@ -483,15 +487,48 @@ Declares a role this Party or Place kind plays with respect to other Parties
483
487
484
488
Target: `Diffo.Provider.Extension.PartyRole`
485
489
490
+
### provider.parties.inherited_party
491
+
```elixir
492
+
inherited_party role
493
+
```
494
+
495
+
496
+
Declares a party derived by traversing the assignment graph — generates a calculation, no PartyRef node created
497
+
498
+
499
+
500
+
501
+
502
+
### Arguments
503
+
504
+
| Name | Type | Default | Docs |
505
+
|------|------|---------|------|
506
+
|[`role`](#provider-parties-inherited_party-role){: #provider-parties-inherited_party-role .spark-required} |`atom`|| The role name — also the default alias to follow on AssignmentRelationship. |
507
+
### Options
508
+
509
+
| Name | Type | Default | Docs |
510
+
|------|------|---------|------|
511
+
|[`source_role`](#provider-parties-inherited_party-source_role){: #provider-parties-inherited_party-source_role .spark-required} |`atom`|| The PartyRef role to pick up on the arrived-at instance. |
512
+
|[`via`](#provider-parties-inherited_party-via){: #provider-parties-inherited_party-via } |`list(atom)`|| Sequence of assignment aliases to traverse. Defaults to [role] for single-hop. Use a list for multi-level. |
@@ -637,6 +676,38 @@ Declares a role this Party or Place kind plays with respect to Places
637
676
638
677
Target: `Diffo.Provider.Extension.PlaceRole`
639
678
679
+
### provider.places.inherited_place
680
+
```elixir
681
+
inherited_place role
682
+
```
683
+
684
+
685
+
Declares a place derived by traversing the assignment graph — generates a calculation, no PlaceRef node created
686
+
687
+
688
+
689
+
690
+
691
+
### Arguments
692
+
693
+
| Name | Type | Default | Docs |
694
+
|------|------|---------|------|
695
+
|[`role`](#provider-places-inherited_place-role){: #provider-places-inherited_place-role .spark-required} |`atom`|| The role name — also the default alias to follow on AssignmentRelationship. |
696
+
### Options
697
+
698
+
| Name | Type | Default | Docs |
699
+
|------|------|---------|------|
700
+
|[`source_role`](#provider-places-inherited_place-source_role){: #provider-places-inherited_place-source_role .spark-required} |`atom`|| The PlaceRef role to pick up on the arrived-at instance. |
701
+
|[`via`](#provider-places-inherited_place-via){: #provider-places-inherited_place-via } |`list(atom)`|| Sequence of assignment aliases to traverse. Defaults to [role] for single-hop. Use a list for multi-level. |
0 commit comments