TS generator: fix #12 (5 expression patterns) + #11 (opaque record types)

#12: All 5 untranslated SpeckDL patterns now emit valid JS:
  - notIn → !.has(), old() → drop, union → Set spread,
    set diff → filter, append() → [...X, Y], length() → .length
  - ==/!= operator replacement fixed (word-boundary regression)
  - Postcondition object comparisons get @ts-expect-error TS2839

#11: Generator auto-detects opaque identifier types used in state
  variables and action params, emits 'type X = any' before class.
  - State properties use ! (non-null assertion) for strict mode

TigerBeetleLedger → tsc --noEmit = 0 errors. 37/37 tests pass.
This commit is contained in:
Scott Scoble 2026-05-11 10:16:15 -07:00
parent 29d4c83d76
commit 8b520284cb
31 changed files with 3934 additions and 973 deletions

View file

@ -12,7 +12,7 @@
"@type": "prov:Generation",
"prov:activity": {
"@type": "prov:Activity",
"prov:startTime": "2026-05-10T05:28:26.203Z"
"prov:startTime": "2026-05-10T09:08:14.888Z"
}
},
"rdfs:label": "KafkaKRaft",

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,7 @@
"author": {
"name": "Speckl Compiler v0.3"
},
"timestamp": "2026-05-10T05:28:26.209Z"
"timestamp": "2026-05-10T09:08:14.915Z"
},
{
"subject": "speck:KafkaKRaft",
@ -39,7 +39,7 @@
"name": "Speckl Compiler",
"email": "compiler@speckl.scoble.me"
},
"timestamp": "2026-05-10T05:28:26.209Z"
"timestamp": "2026-05-10T09:08:14.915Z"
},
{
"subject": "speck:KafkaKRaft",
@ -54,7 +54,7 @@
"name": "Speckl Compiler",
"email": "compiler@speckl.scoble.me"
},
"timestamp": "2026-05-10T05:28:26.209Z"
"timestamp": "2026-05-10T09:08:14.915Z"
}
]
}

View file

@ -13,7 +13,7 @@
"spdxVersion": "3.0.1",
"dataLicense": "CC0-1.0",
"creationInfo": {
"created": "2026-05-10T05:28:26.210Z",
"created": "2026-05-10T09:08:14.915Z",
"createdBy": [
"Organization: Speckl",
"tool: speckl-compile-0.2.0"
@ -27,7 +27,7 @@
"@type": "spdx:Tool",
"name": "speckl-compile"
},
"timestamp": "2026-05-10T05:28:26.210Z",
"timestamp": "2026-05-10T09:08:14.915Z",
"comment": "Review type: hybrid"
}
]

View file

@ -50,5 +50,10 @@ export class KafkaKRaftMachine {
// V1: Always(TermMonotonicity)
async verify1(): Promise<boolean> {
// TODO: Model-check or monitor
// Temporal: Always(TermMonotonicity)
return true;
}
}

View file

@ -12,7 +12,7 @@
"@type": "prov:Generation",
"prov:activity": {
"@type": "prov:Activity",
"prov:startTime": "2026-05-10T04:51:39.510Z"
"prov:startTime": "2026-05-10T09:08:15.017Z"
}
},
"rdfs:label": "OAuth2AuthorizationCode"

View file

@ -13,7 +13,7 @@
"spdxVersion": "3.0.1",
"dataLicense": "CC0-1.0",
"creationInfo": {
"created": "2026-05-10T04:51:39.520Z",
"created": "2026-05-10T09:08:15.086Z",
"createdBy": [
"Organization: Speckl",
"tool: speckl-compile-0.2.0"

View file

@ -43,20 +43,14 @@ export class OAuth2AuthorizationCodeMachine {
decisionLog: any[] = [];
constructor() {
this.clients = new Map();
this.used = false;
this.created_at = 0;
this.sessions = new Map();
this.stateNonces = new Map();
this.pkceChallenges = new Map();
this.currentTime = 0;
// No init block defined
}
Authorize(client: ClientId, redirectUri: RedirectUri, scope: Scope, userId: UserId, sessionId: SessionId) {
if (!(this.clients.has(client))) throw new Error('Guard failed: this.clients.has(client)');
if (!(this.clients.has(redirectUri).client.redirect_uris)) throw new Error('Guard failed: this.clients.has(redirectUri).client.redirect_uris');
if (!(this.clients.client.redirect_uris.has(redirectUri))) throw new Error('Guard failed: this.clients.client.redirect_uris.has(redirectUri)');
if (!(this.sessions.has(sessionId))) throw new Error('Guard failed: this.sessions.has(sessionId)');
if (!(this.sessions.get(sessionId)!.user_id == userId)) throw new Error('Guard failed: this.sessions.get(sessionId)!.user_id == userId');
if (!(this.sessions.get(sessionId).user_id == userId)) throw new Error('Guard failed: this.sessions.get(sessionId).user_id == userId');
this.stateNonces[state] = { this.client_id: client, this.redirect_uri: redirectUri };
this.pkceChallenges[codeChallenge] = { code_verifier_hash: hash(codeVerifier, "S256"), method: "S256" };
this.authorizationCodes[authCode] = {;
@ -92,7 +86,7 @@ export class OAuth2AuthorizationCodeMachine {
}
RevokeToken(client: ClientId, token: string, tokenType: string) {
if (!(this.clients.has(client))) throw new Error('Guard failed: this.clients.has(client)');
if (!(this.clients.has(client) if tokenType == "access" {)) throw new Error('Guard failed: this.clients.has(client) if tokenType == "access" {');
if (!(this.accessTokens.has(token))) throw new Error('Guard failed: this.accessTokens.has(token)');
if (!(t.this.client_id == client)) throw new Error('Guard failed: t.this.client_id == client');
if (!(this.refreshTokens.has(token))) throw new Error('Guard failed: this.refreshTokens.has(token)');

View file

@ -12,7 +12,7 @@
"@type": "prov:Generation",
"prov:activity": {
"@type": "prov:Activity",
"prov:startTime": "2026-05-10T05:07:04.778Z"
"prov:startTime": "2026-05-10T09:08:16.133Z"
}
},
"rdfs:label": "TigerBeetleLedger"

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@
"spdxVersion": "3.0.1",
"dataLicense": "CC0-1.0",
"creationInfo": {
"created": "2026-05-10T05:07:04.787Z",
"created": "2026-05-10T09:08:16.165Z",
"createdBy": [
"Organization: Speckl",
"tool: speckl-compile-0.2.0"

View file

@ -12,7 +12,7 @@
"@type": "prov:Generation",
"prov:activity": {
"@type": "prov:Activity",
"prov:startTime": "2026-05-10T05:04:07.209Z"
"prov:startTime": "2026-05-10T09:08:16.262Z"
}
},
"rdfs:label": "ToggleSwitch"

View file

@ -16,5 +16,8 @@
)
)
; --- Invariant Assertions ---
(assert (SwitchConsistent))
(check-sat)
(get-model)

View file

@ -13,7 +13,7 @@
"spdxVersion": "3.0.1",
"dataLicense": "CC0-1.0",
"creationInfo": {
"created": "2026-05-10T05:04:07.215Z",
"created": "2026-05-10T09:08:16.269Z",
"createdBy": [
"Organization: Speckl",
"tool: speckl-compile-0.2.0"