Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ad13a0e
Apply DSL workarounds for 3 remaining parser limitations
briansrls Mar 28, 2026
e3f5542
Wire RecursionPattern into complexity analyzer; remove body budget guard
briansrls Mar 28, 2026
31b15b0
Fix 3 review comments on PR #228
briansrls Mar 28, 2026
128db02
P5.13B: Algebra registry for kernel type method resolution
briansrls Mar 28, 2026
f9a5074
Add parse-emit round-trip idempotency test
briansrls Mar 28, 2026
653867f
Add Rust SyntaxSpec (second language frontend spec)
briansrls Mar 28, 2026
6e75264
Move syntax types to dsl/std, resolve all import errors
briansrls Mar 28, 2026
f5f2ba9
Remove is_collection guard; all methods resolve via algebra registry
briansrls Mar 28, 2026
d521271
Delete 48 string classification branches (Root Cause B-4)
briansrls Mar 28, 2026
3cc6324
Merge lane-b-codegen-fixes into bold-fox-751
briansrls Mar 28, 2026
e931f67
Delete infer_intrinsic/bridge_method_type_node (parallel implementati…
briansrls Mar 28, 2026
0cc1ea8
Merge origin/main + fix all 13 DSL diagnostics → 0 (94 files emitted)
briansrls Mar 28, 2026
56376e0
Add review workflow and GitHub review operations for .dag compilation
briansrls Mar 28, 2026
758ed5e
Document 3 compiler invariant violations behind DSL diagnostic workar…
briansrls Mar 28, 2026
38adf9a
Dissolve CollectionKind enum — structural predicates replace type ide…
briansrls Mar 28, 2026
af99122
Update ROADMAP + INVARIANTS for CollectionKind dissolution
briansrls Mar 28, 2026
fcadea9
Document compiler structural audit: ~362 hardcoded name-based branches
briansrls Mar 28, 2026
95331e1
Promote compiler thesis inversion to TOP PRIORITY in roadmap
briansrls Mar 28, 2026
3a55110
Update embedded .dag source in generated_tests.rs for CollectionKind …
briansrls Mar 28, 2026
6ddb641
Remove stale collection_kind reference from scrambled-name test comment
briansrls Mar 28, 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
72 changes: 20 additions & 52 deletions INVARIANTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1269,58 +1269,26 @@ will hit the same issue.

---

### CollectionKind is bridge debt (2026-03-26)

**Invariant violated:** Domain lives in the DSL, not in Rust. No case
enumeration for open sets.

`CollectionKind = ListKind | SetKind | MapKind | ...` is a closed enum
on `Node` that the compiler branches on to distinguish collection types.
P5.7b introduced it to replace the worse `properties |> any(p => p.name
== "container_kind")` string-keyed pattern. It is the same class of
violation as the deleted `BuiltinTypeKind` — compiler-side domain
knowledge that should live in `.dag` declarations.

**Why it's fragile (demonstrated 2026-03-26):** Every `Node { ... }`
literal in the codebase must set `collection_kind` correctly, or
`node_is_map`/`node_is_container` silently returns false. Parser-
produced nodes have `collection_kind: none` because the parser doesn't
know about collection kinds. The regression was silent until a test
checked `m[k]` on a `Map<String, Int>` parameter.

**Short-term invariant (per bridge policy):**

- **Canonical authority:** `collection_kind_for_name` in `04_types.dag`.
- **Trust boundary:** Before `resolve_node_bounded`, `collection_kind`
may be absent (parser-produced nodes have `none`). After
normalization at resolve entry, if derivable, it must equal
`collection_kind_for_name(name)`. Treat as a **normalized cache of
name-derived knowledge**, not independent structural truth.
- **Regression test:** `map_index_emits_lookup_style_rust` — the test
that caught the 2026-03-26 regression.
- **Deletion point:** Phase 5 L1=0 gate.

Note: `collection_kind_for_name` is itself a name-checking function —
L1 domain knowledge. The normalization is a mitigation, not a fix.

**Deletion point:** Phase 5 L1=0 gate. When collection types have
real `.dag` declarations with structural method algebras (indexing,
iteration, membership — declared in the type system, not in compiler
enums), `CollectionKind` dissolves. The compiler reads structural
properties from declarations instead of branching on an enum.

**The pure Node model path:** Collections are `.dag` declarations with
arity (already done: `type Map<key, value>`) and method algebras (not
yet: the `.dag` language needs method declarations on types). When
method dispatch reads the type's declared methods instead of a compiler
enum, `node_is_map` becomes "does this type declare an `index` method?"
— a structural query, not a name/enum check.

| # | Severity | Where | What |
|---|----------|-------|------|
| IV-11 | MED | `00_core.dag:120` | `CollectionKind` enum is L1 domain knowledge, same class as deleted `BuiltinTypeKind` |
| IV-12 | MED | `04_types.dag:52` | `collection_kind_for_name` maps names to enum — name-checking function |
| IV-13 | LOW | `04_resolve.dag:197-206` | Normalization at resolve entry — mitigation for parser not setting field |
### CollectionKind — DISSOLVED (2026-03-28)

**Previously:** `CollectionKind` enum (6 variants) on `Node`, 184 sites
across 17 files. Compiler branched on enum to distinguish collection types.
Every `Node { ... }` literal had to set `collection_kind` correctly or
`node_is_map`/`node_is_container` silently returned false.

**Resolution:** Enum deleted, field removed from Node. Collection-ness is
now derived structurally after resolution: containers are the only type
nodes with `children > 0 && connective == NoConnective`. Three structural
predicates (`node_is_collection`, `node_is_keyed_collection`,
`node_is_element_collection`) replace all enum matching. A `container_types`
data list in `00_core.dag` controls which types stay unexpanded during
resolve. Emit uses `to_snake(n.name)` as LanguageSpec template key.

| # | Status | What |
|---|--------|------|
| IV-11 | **FIXED** | `CollectionKind` enum deleted |
| IV-12 | **FIXED** | `collection_kind_for_name` deleted |
| IV-13 | **FIXED** | Normalization block deleted (no field to normalize) |

---

Expand Down
335 changes: 268 additions & 67 deletions ROADMAP.md

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions dsl/extdeps/cloud/gcp/sts.dag
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ type RequestedTokenType = RequestAccessToken | RequestIdToken

// -- Grant type ----------------------------------------------------

type StsGrantType = TokenExchange
// StsGrantType: single value "urn:ietf:params:oauth:grant-type:token-exchange"
// Modeled as String since there is only one grant type for STS.

// -- Token exchange request ----------------------------------------

type StsTokenExchange {
grant_type: StsGrantType
grant_type: String
subject_token: String
subject_token_type: SubjectTokenType
audience: String
Expand Down
111 changes: 111 additions & 0 deletions dsl/extdeps/github/pulls.dag
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,115 @@ service github.Pulls {
404 => { message: "Not Found", documentation_url: "https://docs.github.com/rest" } "Repository or PR not found"
}
}

// Spec: https://docs.github.com/en/rest/pulls/reviews
// Stateless dedup: check if a review exists at a specific commit SHA.
// Returns review count -- 0 means not yet reviewed at this commit.
operation ListReviews {
input {
auth_token: Secret
owner: String
repo: String
pull_number: Int
}
output {
reviews: List<PullReview>
}
readonly
transport rest {
method: GET,
path: "/repos/\{owner\}/\{repo\}/pulls/\{pull_number\}/reviews"
}
response {
200 => List<PullReview>
401 => GitHubErrorShape
404 => GitHubErrorShape
5xx => GitHubErrorShape
}
mock_response {
200 => [] "No reviews yet"
}
}

// Spec: https://docs.github.com/en/rest/pulls/reviews#create-a-review
// Posts a review with line-level comments. Idempotent when guarded
// by ListReviews check (don't post if review at this SHA exists).
operation CreateReview {
input {
auth_token: Secret
owner: String
repo: String
pull_number: Int
commit_id: String
body: String
event: String = "COMMENT"
comments: Json
}
output {
id: Int from "id"
html_url: String from "html_url"
}
transport rest {
method: POST,
path: "/repos/\{owner\}/\{repo\}/pulls/\{pull_number\}/reviews",
body: { commit_id: commit_id, body: body, event: event, comments: comments }
}
response {
200 => Json
401 => GitHubErrorShape
422 => GitHubErrorShape
5xx => GitHubErrorShape
}
mock_response {
200 => { id: 1, html_url: "https://github.com/mock/pull/1#pullrequestreview-1" } "Review created"
}
}

// Spec: https://docs.github.com/en/rest/pulls/comments
// Lists review comments (line-level). Used for resolution checking.
operation ListComments {
input {
auth_token: Secret
owner: String
repo: String
pull_number: Int
}
output {
comments: List<ReviewComment>
}
readonly
transport rest {
method: GET,
path: "/repos/\{owner\}/\{repo\}/pulls/\{pull_number\}/comments"
}
response {
200 => List<ReviewComment>
401 => GitHubErrorShape
404 => GitHubErrorShape
5xx => GitHubErrorShape
}
mock_response {
200 => [] "No comments"
}
}
}

// -- Review and comment types -----------------------------------------

type PullReview {
id: Int
body: String
state: String
commit_id: String
html_url: String
}

type ReviewComment {
id: Int
node_id: String
path: String
line: Int?
original_line: Int?
body: String
html_url: String
}
51 changes: 24 additions & 27 deletions dsl/extdeps/languages/dag/syntax.dag
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@

module extdeps.languages.dag.syntax

import v2.compiler.languages {
import std.syntax {
ItemForm, BodyKind,
ExprBody, BlockBody, TypeBody, ValueBody, NoBody,
ServiceBody, ResourceBody,
OperatorSpec, SyntaxSpec
}

import v2.std.core {
BinOpKind, Add, Sub, Mul, Div, Mod,
BinEq, BinNe, BinLt, BinGt, BinLe, BinGe, BinAnd, BinOr, NullCoalesce,
LiteralValue, LitBool, LitNull
OperatorSpec, SyntaxSpec,
BinOp, OpAdd, OpSub, OpMul, OpDiv, OpMod,
OpEq, OpNe, OpLt, OpGt, OpLe, OpGe, OpAnd, OpOr, OpNullCoalesce,
LiteralKind, BoolLiteral, NullLiteral
}

// Item forms: keyword -> structural components + body kind.
Expand Down Expand Up @@ -57,11 +54,11 @@ data dag_item_forms: List<ItemForm> = [
// Literal keywords: keyword text -> LiteralValue.
// The parser checks this map before expression keywords.

data dag_keyword_literals: Map<String, LiteralValue> = {
"true": LitBool { value: true },
"false": LitBool { value: false },
"none": LitNull,
"null": LitNull
data dag_keyword_literals: Map<String, LiteralKind> = {
"true": BoolLiteral { value: true },
"false": BoolLiteral { value: false },
"none": NullLiteral,
"null": NullLiteral
}

// Keyword lookup map — the single authority for what strings are keywords.
Expand All @@ -86,20 +83,20 @@ data dag_keyword_set: Map<String, Bool> = {
// (the expression loop handles them as pipe/field-access, not binary ops).

data dag_operators: List<OperatorSpec> = [
OperatorSpec { symbol: "??", left_bp: 3, right_bp: 4, binop: NullCoalesce },
OperatorSpec { symbol: "||", left_bp: 5, right_bp: 6, binop: BinOr },
OperatorSpec { symbol: "&&", left_bp: 7, right_bp: 8, binop: BinAnd },
OperatorSpec { symbol: "==", left_bp: 9, right_bp: 10, binop: BinEq },
OperatorSpec { symbol: "!=", left_bp: 9, right_bp: 10, binop: BinNe },
OperatorSpec { symbol: "<", left_bp: 11, right_bp: 12, binop: BinLt },
OperatorSpec { symbol: ">", left_bp: 11, right_bp: 12, binop: BinGt },
OperatorSpec { symbol: "<=", left_bp: 11, right_bp: 12, binop: BinLe },
OperatorSpec { symbol: ">=", left_bp: 11, right_bp: 12, binop: BinGe },
OperatorSpec { symbol: "+", left_bp: 13, right_bp: 14, binop: Add },
OperatorSpec { symbol: "-", left_bp: 13, right_bp: 14, binop: Sub },
OperatorSpec { symbol: "*", left_bp: 15, right_bp: 16, binop: Mul },
OperatorSpec { symbol: "/", left_bp: 15, right_bp: 16, binop: Div },
OperatorSpec { symbol: "%", left_bp: 15, right_bp: 16, binop: Mod },
OperatorSpec { symbol: "??", left_bp: 3, right_bp: 4, binop: OpNullCoalesce },
OperatorSpec { symbol: "||", left_bp: 5, right_bp: 6, binop: OpOr },
OperatorSpec { symbol: "&&", left_bp: 7, right_bp: 8, binop: OpAnd },
OperatorSpec { symbol: "==", left_bp: 9, right_bp: 10, binop: OpEq },
OperatorSpec { symbol: "!=", left_bp: 9, right_bp: 10, binop: OpNe },
OperatorSpec { symbol: "<", left_bp: 11, right_bp: 12, binop: OpLt },
OperatorSpec { symbol: ">", left_bp: 11, right_bp: 12, binop: OpGt },
OperatorSpec { symbol: "<=", left_bp: 11, right_bp: 12, binop: OpLe },
OperatorSpec { symbol: ">=", left_bp: 11, right_bp: 12, binop: OpGe },
OperatorSpec { symbol: "+", left_bp: 13, right_bp: 14, binop: OpAdd },
OperatorSpec { symbol: "-", left_bp: 13, right_bp: 14, binop: OpSub },
OperatorSpec { symbol: "*", left_bp: 15, right_bp: 16, binop: OpMul },
OperatorSpec { symbol: "/", left_bp: 15, right_bp: 16, binop: OpDiv },
OperatorSpec { symbol: "%", left_bp: 15, right_bp: 16, binop: OpMod },
OperatorSpec { symbol: "|>", left_bp: 17, right_bp: 18, binop: none },
OperatorSpec { symbol: ".", left_bp: 19, right_bp: 20, binop: none }
]
Expand Down
1 change: 1 addition & 0 deletions dsl/extdeps/languages/go/emit.dag
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ data go_keywords: Map<String, String> = {
// Ref: Go Spec, Composite literals
data go_container_templates: Map<String, String> = {
"list": "[]\{0\}", "set": "map[\{0\}]struct{}",
"non_empty_list": "[]\{0\}", "non_empty_set": "map[\{0\}]struct{}",
"optional": "*\{0\}", "map": "map[\{0\}]\{1\}"
}

Expand Down
1 change: 1 addition & 0 deletions dsl/extdeps/languages/python/emit.dag
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ data python_keywords: Map<String, String> = {
// Ref: typing module (PEP 585)
data python_container_templates: Map<String, String> = {
"list": "list[\{0\}]", "set": "set[\{0\}]",
"non_empty_list": "list[\{0\}]", "non_empty_set": "set[\{0\}]",
"optional": "Optional[\{0\}]", "map": "dict[\{0\}, \{1\}]"
}

Expand Down
Loading
Loading