Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
186ea32
WIP: Path (a) full-stack omni-emission visceral demo: write dsl/demos…
briansrls May 13, 2026
7705b84
chore: apply cargo fmt (todo_service omni test)
briansrls May 13, 2026
fd3ec71
WIP: Path (a) full-stack omni-emission visceral demo: write dsl/demos…
briansrls May 13, 2026
b8a2e8a
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
41916b6
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
532bab7
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
2e78620
test(omni): use counted compile helper for todo_service demo (parity …
briansrls May 13, 2026
0c34c28
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
1746120
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
7b5e230
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
75146e4
demo(todo_service): add example data rows so domain types are inhabited
briansrls May 13, 2026
ef28f06
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
ba37963
test(omni): rustc+probe todo_service backend against canonical routes
briansrls May 13, 2026
5bb6ab2
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
5c76d28
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
ce9ea98
WIP: Path (a) full-stack omni-emission visceral demo: write dsl/demos…
briansrls May 13, 2026
3e9675d
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
25c5196
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
deec258
Merge remote-tracking branch 'origin/main' into session/merry-ram-238
briansrls May 13, 2026
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
167 changes: 167 additions & 0 deletions dsl/demos/todo_service.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// demos/todo_service — minimal TODO domain + REST operation table for omni-emission demos.
//
// Exercises Shape B projections in `omni_shape_b_openapi.rs` (OpenAPI 3.1 YAML,
// Markdown drift-lock, SQL DDL route schema, runnable Rust backend) plus Shape A
// `emit_rust` on one shared `compile_to_dag` result (r3-program-plan §1.8 #25–#28).
//
// Domain carriers are illustrated with small `data` inhabitants (human-facing
// demo context). Omni route extraction still keys only on
// `List<{ endpoint: RestEndpointBinding }>` rows (`v3.std.services`).

module demos.todo_service

import std.types { GET, POST, PUT, PATCH, DELETE, Int, String, Bool }
import std.effects { LiteralToken, ParamToken }
import v3.std.services { RestEndpointBinding }

// Trivial root `let` so the module is not purely type-level (same cadence as
// `omni_emit_anchor` in `m1_5_omni_shape_b_openapi_test` inline fixtures). Unused by route
// extractors; keeps demo symmetry with other omni Shape B receipts.
let todo_service_emit_anchor: Int = 0

type User {
id: String
display_name: String
}

type TodoItem {
id: String
list_id: String
title: String
completed: Bool
}

type TodoList {
id: String
owner_id: String
title: String
}

type TodoServiceOperation {
endpoint: RestEndpointBinding
}

data todo_domain_example_user: User = {
id: "demo-user",
display_name: "Demo User"
}

data todo_domain_example_item: TodoItem = {
id: "demo-todo",
list_id: "demo-list",
title: "Wire domain carriers to example rows",
completed: false
}

data todo_domain_example_list: TodoList = {
id: "demo-list",
owner_id: "demo-user",
title: "Demo backlog"
}

data todo_service_operations: List<TodoServiceOperation> = [
{
endpoint: {
method: GET,
path: { tokens: [LiteralToken { text: "users" }] }
}
},
{
endpoint: {
method: POST,
path: { tokens: [LiteralToken { text: "users" }] }
}
},
{
endpoint: {
method: GET,
path: {
tokens: [LiteralToken { text: "users/" }, ParamToken { name: "userId" }]
}
}
},
{
endpoint: {
method: PUT,
path: {
tokens: [LiteralToken { text: "users/" }, ParamToken { name: "userId" }]
}
}
},
{
endpoint: {
method: DELETE,
path: {
tokens: [LiteralToken { text: "users/" }, ParamToken { name: "userId" }]
}
}
},
{
endpoint: {
method: GET,
path: {
tokens: [
LiteralToken { text: "users/" },
ParamToken { name: "userId" },
LiteralToken { text: "/todos" }
]
}
}
},
{
endpoint: {
method: POST,
path: {
tokens: [
LiteralToken { text: "users/" },
ParamToken { name: "userId" },
LiteralToken { text: "/todos" }
]
}
}
},
{
endpoint: {
method: GET,
path: {
tokens: [LiteralToken { text: "todos/" }, ParamToken { name: "todoId" }]
}
}
},
{
endpoint: {
method: PATCH,
path: {
tokens: [LiteralToken { text: "todos/" }, ParamToken { name: "todoId" }]
}
}
},
{
endpoint: {
method: DELETE,
path: {
tokens: [LiteralToken { text: "todos/" }, ParamToken { name: "todoId" }]
}
}
},
{
endpoint: {
method: GET,
path: {
tokens: [LiteralToken { text: "lists/" }, ParamToken { name: "listId" }]
}
}
},
{
endpoint: {
method: POST,
path: {
tokens: [
LiteralToken { text: "lists/" },
ParamToken { name: "listId" },
LiteralToken { text: "/todos" }
]
}
}
}
]
153 changes: 153 additions & 0 deletions src/v3/compiler/tests/integration/m1_5_omni_shape_b_openapi_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ import std.types { Int }
let omni_emit_anchor: Int = 0
"#;

const TODO_SERVICE_REPOSITORY_SOURCE: &str =

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BLOCKING: Expanded hand-authored Rust under src/v3 needs exactly one P5 receipt in the PR body or a changed planning artifact; this diff provides none, so INVARIANTS.md P5 is not satisfied.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

P5 (INVARIANTS §mechanism (b)) — addressed on the PR: Body now has SG-0 hand-path delta: +0 and one checkable receipt (ROADMAP ### Lane acceptance — .dag gates / T-Emit / emit_omni_demo_fixtures_green, PR #1051). Rust edits stay in census-listed m1_5_omni_shape_b_openapi_test.rs. Please Resolve this thread: #2848 (comment)

— sent from merry-ram-238

include_str!("../../../../../dsl/demos/todo_service.dag");

fn compile_omni_service_fixture() -> v3_compiler::Dag {
std::thread::Builder::new()
.name("m1_5_openapi_fixture_compile".to_string())
Expand Down Expand Up @@ -161,6 +164,89 @@ fn compile_empty_omni_service_fixture() -> v3_compiler::Dag {
.expect("larger-stack compile thread completes")
}

fn compile_todo_service_repository_fixture() -> v3_compiler::Dag {
std::thread::Builder::new()
.name("m1_5_todo_service_repository_compile".to_string())
.stack_size(32 * 1024 * 1024)
.spawn(|| {
compile_to_dag(TODO_SERVICE_REPOSITORY_SOURCE, "dsl/demos/todo_service.dag")
.expect("repository todo_service.dag demo compiles")
})
.expect("spawn larger-stack compile thread")
.join()
.expect("larger-stack compile thread completes")
}

fn compile_todo_service_repository_fixture_counted(count: &mut usize) -> v3_compiler::Dag {
*count += 1;
compile_todo_service_repository_fixture()
}

fn expected_todo_service_routes() -> BTreeSet<RestRoute> {
BTreeSet::from([
RestRoute {
method: "DELETE".to_string(),
path: "/todos/{todoId}".to_string(),
path_parameters: vec!["todoId".to_string()],
},
RestRoute {
method: "DELETE".to_string(),
path: "/users/{userId}".to_string(),
path_parameters: vec!["userId".to_string()],
},
RestRoute {
method: "GET".to_string(),
path: "/lists/{listId}".to_string(),
path_parameters: vec!["listId".to_string()],
},
RestRoute {
method: "GET".to_string(),
path: "/todos/{todoId}".to_string(),
path_parameters: vec!["todoId".to_string()],
},
RestRoute {
method: "GET".to_string(),
path: "/users".to_string(),
path_parameters: vec![],
},
RestRoute {
method: "GET".to_string(),
path: "/users/{userId}".to_string(),
path_parameters: vec!["userId".to_string()],
},
RestRoute {
method: "GET".to_string(),
path: "/users/{userId}/todos".to_string(),
path_parameters: vec!["userId".to_string()],
},
RestRoute {
method: "PATCH".to_string(),
path: "/todos/{todoId}".to_string(),
path_parameters: vec!["todoId".to_string()],
},
RestRoute {
method: "POST".to_string(),
path: "/lists/{listId}/todos".to_string(),
path_parameters: vec!["listId".to_string()],
},
RestRoute {
method: "POST".to_string(),
path: "/users".to_string(),
path_parameters: vec![],
},
RestRoute {
method: "POST".to_string(),
path: "/users/{userId}/todos".to_string(),
path_parameters: vec!["userId".to_string()],
},
RestRoute {
method: "PUT".to_string(),
path: "/users/{userId}".to_string(),
path_parameters: vec!["userId".to_string()],
},
])
}

fn expected_routes() -> BTreeSet<RestRoute> {
BTreeSet::from([
RestRoute {
Expand Down Expand Up @@ -700,3 +786,70 @@ fn openapi_projection_ignores_same_shape_non_service_endpoint_binding() {
an OpenAPI route unless its field type is the canonical RestEndpointBinding."
);
}

/// Repository `dsl/demos/todo_service.dag` visceral demo: one `compile_to_dag` feeds the
/// four Shape B projections (OpenAPI YAML, Markdown, SQL DDL, Rust backend) plus Shape A
/// `emit_rust`, matching r3-program-plan §1.8 #25–#28 structural discipline.
#[test]
fn todo_service_repository_demo_omni_layers_share_one_node_tree() {
// `compile_count` mirrors `omni_layers_share_one_node_tree`: one shared `Dag` is already
// enforced structurally because every projection takes `&dag`. The counter still ratchets
// accidental double acquisition via `compile_*_counted` (e.g. a duplicated helper call
// during edits), matching the §1.8 #28 receipt style in this module.
let mut compile_count = 0usize;
let dag = compile_todo_service_repository_fixture_counted(&mut compile_count);

let canonical = extract_rest_routes(&dag).expect("canonical route projection extracts");
assert_eq!(canonical, expected_todo_service_routes());

let openapi = project_openapi_yaml(&dag).expect("Shape B OpenAPI projects from shared DAG");
assert!(openapi.starts_with("openapi: 3.1.0\n"));
assert_eq!(openapi_yaml_routes(&openapi), canonical);

let markdown = project_markdown_documentation(&dag).expect("Markdown projects from shared DAG");
assert_eq!(markdown_documentation_routes(&markdown), canonical);

let ddl = project_sql_ddl_schema(&dag).expect("SQL DDL projects from shared DAG");
let ddl_routes = sql_ddl_routes(&ddl);
let canonical_without_parameters: BTreeSet<_> = canonical
.iter()
.map(|route| RestRoute {
method: route.method.clone(),
path: route.path.clone(),
path_parameters: vec![],
})
.collect();
assert_eq!(ddl_routes, canonical_without_parameters);
assert!(ddl.contains(" CHECK (method IN ("));
assert!(ddl.contains("'DELETE'"));
assert!(ddl.contains("'PATCH'"));
assert!(ddl.contains("'PUT'"));

let backend_source =
project_rust_backend_service(&dag).expect("backend service projects from shared DAG");
let (_tmp_dir, backend_bin) = compile_backend_service(&backend_source);
for route in &canonical {
let concrete_path = route
.path
.replace("{userId}", "42")
.replace("{todoId}", "99")
.replace("{listId}", "7");
assert_eq!(
backend_probe(&backend_bin, &route.method, &concrete_path),
"200",
"generated backend accepts route {} {}",
route.method,
concrete_path
);
}
assert_eq!(backend_probe(&backend_bin, "GET", "/missing"), "404");
assert_eq!(backend_probe(&backend_bin, "DELETE", "/users"), "404");
assert_eq!(backend_probe(&backend_bin, "GET", "/users/"), "404");

let _rust = emit_rust(&dag).expect("Shape A Rust emit consumes shared DAG");

assert_eq!(
compile_count, 1,
"Shape A + Shape B layers must consume the same compile_to_dag result for the repository demo"
);
}
Loading