Skip to content

Commit fe81cd1

Browse files
authored
Merge pull request ossuminc#721 from ossuminc/development
Release 1.8.0: Validation deep checks
2 parents 8d2e6a8 + 896956f commit fe81cd1

17 files changed

Lines changed: 797 additions & 155 deletions

File tree

CLAUDE.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,3 +704,33 @@ Then add to root aggregation: `.aggregate(..., mymodule, mymoduleJS, mymoduleNat
704704
40. **RiddlLib analysis API methods** - `getHandlerCompleteness()`, `getMessageFlow()`, `getEntityLifecycles()` on shared RiddlLib trait + JS `RiddlAPI` facade. Each runs standard passes plus the relevant analysis pass
705705
41. **HandlerCompleteness in ValidationOutput** - `ValidationOutput.handlerCompleteness: Seq[HandlerCompleteness]` populated in `ValidationPass.postProcess()`. Categories: `BehaviorCategory.Executable`, `PromptOnly`, `Empty`
706706
42. **Downstream integration plans** - Each downstream project (riddlsim, riddl-gen, riddl-mcp-server, synapify) has a `RIDDL-INTEGRATION-PLAN.md` describing how to consume new library features. Designed for separate Claude instances working in those projects
707+
43. **gh CLI requires unset GITHUB_TOKEN** - When using `gh`
708+
commands locally, `unset GITHUB_TOKEN` first so `gh` uses the
709+
user's keychain credentials instead of the (possibly expired
710+
or wrong-scope) env var
711+
44. **PR merge with branch protection** - Use
712+
`gh pr merge --admin --merge --delete-branch=false` to bypass
713+
branch protection when merging development→main for releases
714+
45. **RiddlLib.ast2bast(root)** - Converts parsed AST to BAST
715+
binary bytes. Shared trait returns `Array[Byte]`, JS facade
716+
returns `Int8Array`. Uses BASTWriterPass internally. Test
717+
verifies BAST magic header bytes
718+
46. **Consumer update notes** - `RIDDL-UPDATE-NOTES.md` in
719+
synapify, riddl-mcp-server, ossum.ai covers 1.5.0 breaking
720+
change (opaque Root) and 1.7.0 new functions. Separate from
721+
the detailed `RIDDL-INTEGRATION-PLAN.md` files
722+
47. **Schema parser uses `time-series` (hyphenated)** - The
723+
`schemaKind` parser in RepositoryParser.scala expects
724+
`"time-series"`, not `"timeseries"`. Check `StringIn(...)`
725+
in `schemaKind` for all valid schema kind keywords
726+
48. **Consecutive schemas need `with` terminators** - Schema
727+
definitions inside a repository need `with { ... }` blocks
728+
to terminate because `data.rep(1)` is greedy and consumes
729+
subsequent `of` clauses. Without `with`, the parser can't
730+
find the boundary between consecutive schemas
731+
49. **Adaptor cross-context type resolution** - Use parent-
732+
independent `resolution.refMap.definitionOf[Type](pathId)`
733+
(no parent arg) for resolving types referenced in adaptor
734+
handlers. The parent-keyed overload fails because the
735+
resolution pass stores refs keyed under the OnMessageClause
736+
parent, not the adaptor's parent

NOTEBOOK.md

Lines changed: 228 additions & 150 deletions
Large diffs are not rendered by default.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
passes/input/check/adaptor-direction/adaptor-direction.riddl(12:9->34):
2+
Inbound Adaptor 'BadInbound' handles Command 'SourceCtx.DoIt' from Context 'SourceCtx', but inbound adaptors should handle events and results (the target's output):
3+
on command SourceCtx.DoIt {
4+
passes/input/check/adaptor-direction/adaptor-direction.riddl(12:9->34):
5+
Processing for commands should result in sending an event:
6+
on command SourceCtx.DoIt {
7+
passes/input/check/adaptor-direction/adaptor-direction.riddl(22:9->34):
8+
Outbound Adaptor 'BadOutbound' handles Event 'SourceCtx.ItDone' from Context 'SourceCtx', but outbound adaptors should handle commands and queries (the target's input):
9+
on event SourceCtx.ItDone {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
domain AdaptorDir is {
2+
context SourceCtx is {
3+
type DoIt is command { data: String }
4+
type ItDone is event { what: String }
5+
} with {
6+
explained as "Source context with message types"
7+
}
8+
9+
context TargetCtx is {
10+
adaptor BadInbound from context SourceCtx is {
11+
handler InHandler is {
12+
on command SourceCtx.DoIt {
13+
prompt "handling command in inbound adaptor"
14+
}
15+
}
16+
} with {
17+
explained as "Inbound adaptor that incorrectly handles commands"
18+
}
19+
20+
adaptor BadOutbound to context SourceCtx is {
21+
handler OutHandler is {
22+
on event SourceCtx.ItDone {
23+
prompt "handling event in outbound adaptor"
24+
}
25+
}
26+
} with {
27+
explained as "Outbound adaptor that incorrectly handles events"
28+
}
29+
} with {
30+
explained as "Target context with adaptors"
31+
}
32+
} with {
33+
explained as "Domain for adaptor direction tests"
34+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
passes/input/check/handler-types/handler-types.riddl(12:7->27):
2+
Handler 'EventHandler' in Repository 'EventRepo' handles events; repositories typically handle commands and queries, not events:
3+
handler EventHandler is {
4+
passes/input/check/handler-types/handler-types.riddl(21:5->27):
5+
Projector 'CmdProjector' handler does not handle any events; projectors typically handle events to build read models:
6+
projector CmdProjector is {
7+
passes/input/check/handler-types/handler-types.riddl(22:7->22):
8+
Record 'ProjRecord' is unused:
9+
type ProjRecord is record { field1: String }
10+
passes/input/check/handler-types/handler-types.riddl(23:7->25):
11+
Handler 'CmdHandler' in Projector 'CmdProjector' handles commands or queries; projectors typically handle events to build read models:
12+
handler CmdHandler is {
13+
passes/input/check/handler-types/handler-types.riddl(24:9->31):
14+
Processing for commands should result in sending an event:
15+
on command SomeCommand {
16+
passes/input/check/handler-types/handler-types.riddl(5:5->20):
17+
Record 'RecordType' is unused:
18+
type RecordType is record { field1: String }
19+
passes/input/check/handler-types/handler-types.riddl(7:5->25):
20+
Repository 'EventRepo' handlers do not handle any commands or queries; repositories typically handle commands (for mutations) and queries (for reads):
21+
repository EventRepo is {
22+
passes/input/check/handler-types/handler-types.riddl(8:7->24):
23+
Schema 'RepoSchema' should have a description:
24+
schema RepoSchema is flat
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
domain HandlerTypes is {
2+
context TypeCtx is {
3+
type SomeEvent is event { what: String }
4+
type SomeCommand is command { data: String }
5+
type RecordType is record { field1: String }
6+
7+
repository EventRepo is {
8+
schema RepoSchema is flat
9+
of records as type RecordType
10+
with { briefly as "Repo schema" }
11+
12+
handler EventHandler is {
13+
on event SomeEvent {
14+
prompt "handling event in repo"
15+
}
16+
}
17+
} with {
18+
explained as "Repository that handles events"
19+
}
20+
21+
projector CmdProjector is {
22+
type ProjRecord is record { field1: String }
23+
handler CmdHandler is {
24+
on command SomeCommand {
25+
prompt "handling command in projector"
26+
}
27+
}
28+
} with {
29+
explained as "Projector that handles commands"
30+
}
31+
} with {
32+
explained as "Context for handler type tests"
33+
}
34+
} with {
35+
explained as "Domain for handler type tests"
36+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
passes/input/check/schema-kinds/schema-kinds.riddl(7:7->23):
2+
Schema 'FlatMulti' is flat but defines 2 data nodes; flat schemas typically represent a single table or collection:
3+
schema FlatMulti is flat
4+
passes/input/check/schema-kinds/schema-kinds.riddl(7:7->23):
5+
Schema 'FlatMulti' should have a description:
6+
schema FlatMulti is flat
7+
passes/input/check/schema-kinds/schema-kinds.riddl(12:7->23):
8+
Schema 'TSNoIndex' is a time-series schema but has no indices; time-series schemas should index the time dimension:
9+
schema TSNoIndex is time-series
10+
passes/input/check/schema-kinds/schema-kinds.riddl(12:7->23):
11+
Schema 'TSNoIndex' should have a description:
12+
schema TSNoIndex is time-series
13+
passes/input/check/schema-kinds/schema-kinds.riddl(16:7->25):
14+
Schema 'HierNoLinks' is hierarchical with 2 data nodes but has no links; consider adding links to define the tree structure:
15+
schema HierNoLinks is hierarchical
16+
passes/input/check/schema-kinds/schema-kinds.riddl(16:7->25):
17+
Schema 'HierNoLinks' should have a description:
18+
schema HierNoLinks is hierarchical
19+
passes/input/check/schema-kinds/schema-kinds.riddl(21:7->25):
20+
Schema 'StarNoLinks' is a star schema with 2 data nodes but has no links; consider adding links from fact table to dimension tables:
21+
schema StarNoLinks is star
22+
passes/input/check/schema-kinds/schema-kinds.riddl(21:7->25):
23+
Schema 'StarNoLinks' should have a description:
24+
schema StarNoLinks is star
25+
passes/input/check/schema-kinds/schema-kinds.riddl(26:7->26):
26+
Handler 'RepoHandler' in Repository 'SchemaRepo' should have content:
27+
handler RepoHandler is { ??? }
28+
passes/input/check/schema-kinds/schema-kinds.riddl(3:5->18):
29+
Type 'Customer' is unused:
30+
type Customer is { name: String, email: String, age: Number }
31+
passes/input/check/schema-kinds/schema-kinds.riddl(4:5->19):
32+
Type 'OrderInfo' is unused:
33+
type OrderInfo is { orderId: UUID, amount: Number, date: Date }
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
domain SchemaKinds is {
2+
context DataCtx is {
3+
type Customer is { name: String, email: String, age: Number }
4+
type OrderInfo is { orderId: UUID, amount: Number, date: Date }
5+
6+
repository SchemaRepo is {
7+
schema FlatMulti is flat
8+
of customers as type Customer
9+
of orders as type OrderInfo
10+
with { briefly as "Flat schema with multiple data nodes" }
11+
12+
schema TSNoIndex is time-series
13+
of metrics as type Customer
14+
with { briefly as "Time-series schema without indices" }
15+
16+
schema HierNoLinks is hierarchical
17+
of parent as type Customer
18+
of child as type OrderInfo
19+
with { briefly as "Hierarchical schema without links" }
20+
21+
schema StarNoLinks is star
22+
of fact as type Customer
23+
of dim as type OrderInfo
24+
with { briefly as "Star schema without links" }
25+
26+
handler RepoHandler is { ??? }
27+
} with {
28+
explained as "Repository for schema kind validation tests"
29+
}
30+
} with {
31+
explained as "Context for schema kind tests"
32+
}
33+
} with {
34+
explained as "Domain for schema kind tests"
35+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
passes/input/check/sink-reach/sink-reach.riddl(12:5->18):
2+
Sink 'Consumer' is a sink but has no upstream path from any source:
3+
sink Consumer is {
4+
passes/input/check/sink-reach/sink-reach.riddl(12:5->18):
5+
Sink 'Consumer' should have a handler:
6+
sink Consumer is {
7+
passes/input/check/sink-reach/sink-reach.riddl(5:5->19):
8+
Flow 'Processor' should have a handler:
9+
flow Processor is {
10+
passes/input/check/sink-reach/sink-reach.riddl(6:7->19):
11+
Inlet 'DataIn' is not connected:
12+
inlet DataIn is type Data
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
domain SinkReach is {
2+
context StreamCtx is {
3+
type Data is String
4+
5+
flow Processor is {
6+
inlet DataIn is type Data
7+
outlet DataOut is type Data
8+
} with {
9+
explained as "A flow processor"
10+
}
11+
12+
sink Consumer is {
13+
inlet ConsumeIn is type Data
14+
} with {
15+
explained as "A data consumer sink"
16+
}
17+
18+
connector FlowToSink is {
19+
from outlet StreamCtx.Processor.DataOut
20+
to inlet StreamCtx.Consumer.ConsumeIn
21+
} with {
22+
explained as "Connect flow output to sink input"
23+
}
24+
} with {
25+
explained as "Context for sink reachability test"
26+
}
27+
} with {
28+
explained as "Domain for sink reachability test"
29+
}

0 commit comments

Comments
 (0)