diff --git a/migration/modules/CloudGuardModule.affine b/migration/modules/CloudGuardModule.affine new file mode 100644 index 0000000..51dc5e9 --- /dev/null +++ b/migration/modules/CloudGuardModule.affine @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// CloudGuardModule.affine — capability-driven registration for the +// Cloudflare domain security management panel. +// +// Translation of src/modules/CloudGuardModule.res (93 LoC). Same shape +// as the other module files plus an extra `capabilityDescription` +// helper (CloudGuard tooltips include longer prose). +// +// Refs: standards#279, standards#252. + +module CloudGuardModule; + +use prelude::{Option, Some, None, contains}; + +type CloudguardCapability = + | DomainInventory + | SecurityHardening + | DnsManagement + | ComplianceAudit + | OfflineConfig + | BulkOperations + | PagesIntegration + | DnssecManagement + +type CloudguardModuleConfig = { + id: String, + name: String, + version: String, + description: String, + apiEndpoint: String, + capabilities: [CloudguardCapability], + icon: Option, +} + +const config: CloudguardModuleConfig = #{ + id: "cloudguard", + name: "CloudGuard", + version: "0.1.0", + description: "Cloudflare domain security management. Automates SSL/TLS hardening, DNS security records, WAF configuration, DNSSEC, and compliance auditing across all domains.", + apiEndpoint: "https://api.cloudflare.com/client/v4", + capabilities: [ + DomainInventory, + SecurityHardening, + DnsManagement, + ComplianceAudit, + OfflineConfig, + BulkOperations, + PagesIntegration, + DnssecManagement, + ], + icon: Some("shield"), +}; + +fn hasCapability(cap: CloudguardCapability) -> Bool { + contains(config.capabilities, cap) +} + +fn capabilityLabel(cap: CloudguardCapability) -> String { + match cap { + DomainInventory => "Domain Inventory", + SecurityHardening => "Security Hardening", + DnsManagement => "DNS Management", + ComplianceAudit => "Compliance Audit", + OfflineConfig => "Offline Config", + BulkOperations => "Bulk Operations", + PagesIntegration => "Pages Integration", + DnssecManagement => "DNSSEC Management", + } +} + +fn capabilityDescription(cap: CloudguardCapability) -> String { + match cap { + DomainInventory => "List and monitor all Cloudflare zones with plan tier, status, and nameserver info", + SecurityHardening => "Apply SSL Full (Strict), HSTS, min TLS 1.2, security headers, and other hardening defaults", + DnsManagement => "Create, update, and delete DNS records with templates for SPF, DMARC, DKIM, CAA, and TLSRPT", + ComplianceAudit => "Evaluate live Cloudflare settings against Trustfile/Nickel security policy constraints", + OfflineConfig => "Download zone configs as JSON, edit offline, upload with three-way diff and dry-run preview", + BulkOperations => "Apply hardening settings across all selected domains with real-time progress tracking", + PagesIntegration => "Set up Cloudflare Pages projects from GitHub repos with auto-detected SSG framework", + DnssecManagement => "Enable DNSSEC, verify DS records at registrar, monitor key rotation status", + } +} diff --git a/migration/modules/FarmModule.affine b/migration/modules/FarmModule.affine new file mode 100644 index 0000000..098e5e2 --- /dev/null +++ b/migration/modules/FarmModule.affine @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// FarmModule.affine — capability registration for the Git-Private-Farm panel. +// +// Translation of src/modules/FarmModule.res (66 LoC). Same capability- +// declaration shape as the other panll module files: sum-type capability, +// config record, hasCapability + capabilityLabel helpers. Pure data + +// pure functions — no FFI / Tea_/ Pixi / Gossamer surface. +// +// Refs: standards#279 (megaport step), standards#252 (campaign umbrella). + +module FarmModule; + +use prelude::{Option, Some, None, contains}; + +/// Capabilities that the Farm panel exposes. +type FarmCapability = + | RepoInventory + | EnrollmentDashboard + | HealthDashboard + | GroupAnalysis + | ForgeCoverage + +type FarmModuleConfig = { + id: String, + name: String, + version: String, + description: String, + manifestPath: String, + capabilities: [FarmCapability], + icon: Option, +} + +const config: FarmModuleConfig = #{ + id: "farm", + name: "Git-Private-Farm", + version: "0.1.0", + description: "Repository admin registry and maintenance hub for ~265 repos across 6 forges", + manifestPath: "~/.git-private-farm/farm-manifest.json", + capabilities: [RepoInventory, EnrollmentDashboard, HealthDashboard, GroupAnalysis, ForgeCoverage], + icon: Some("barn"), +}; + +fn hasCapability(cap: FarmCapability) -> Bool { + contains(config.capabilities, cap) +} + +fn capabilityLabel(cap: FarmCapability) -> String { + match cap { + RepoInventory => "Repo Inventory", + EnrollmentDashboard => "Enrollment Dashboard", + HealthDashboard => "Health Dashboard", + GroupAnalysis => "Group Analysis", + ForgeCoverage => "Forge Coverage", + } +} diff --git a/migration/modules/LanguageForgeModule.affine b/migration/modules/LanguageForgeModule.affine new file mode 100644 index 0000000..8e98162 --- /dev/null +++ b/migration/modules/LanguageForgeModule.affine @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// LanguageForgeModule.affine — capability registration for the +// nextgen-languages panel. +// +// Translation of src/modules/LanguageForgeModule.res (60 LoC). Same shape +// as the other module files. +// +// Refs: standards#279, standards#252. + +module LanguageForgeModule; + +use prelude::{Option, Some, None, contains}; + +type LanguageForgeCapability = + | LanguageDashboard + | CompilationStatus + | MoscowView + | WasmTargetTracker + +type LanguageForgeModuleConfig = { + id: String, + name: String, + version: String, + description: String, + capabilities: [LanguageForgeCapability], + icon: Option, +} + +const config: LanguageForgeModuleConfig = #{ + id: "language-forge", + name: "Language Forge", + version: "0.1.0", + description: "Monitor and develop the 14 nextgen-languages portfolio — scores, phases, WASM readiness", + capabilities: [LanguageDashboard, CompilationStatus, MoscowView, WasmTargetTracker], + icon: Some("hammer"), +}; + +fn hasCapability(cap: LanguageForgeCapability) -> Bool { + contains(config.capabilities, cap) +} + +fn capabilityLabel(cap: LanguageForgeCapability) -> String { + match cap { + LanguageDashboard => "Language Dashboard", + CompilationStatus => "Compilation Status", + MoscowView => "MoSCoW View", + WasmTargetTracker => "WASM Target Tracker", + } +} diff --git a/migration/modules/MassPanicModule.affine b/migration/modules/MassPanicModule.affine new file mode 100644 index 0000000..9d7a173 --- /dev/null +++ b/migration/modules/MassPanicModule.affine @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// MassPanicModule.affine — capability declarations for the +// organisation-scale batch scanning panel. +// +// Translation of src/modules/MassPanicModule.res (66 LoC). Same shape. +// +// Refs: standards#279, standards#252. + +module MassPanicModule; + +use prelude::{Option, Some, None, contains}; + +type MassPanicCapability = + | AssemblylineScanning + | IncrementalBlake3 + | VerisimDBPersistence + | DeltaReporting + | NotificationPipeline + | RepoDiscovery + | CacheManagement + | SystemImaging + | TemporalNavigation + +type MassPanicModuleConfig = { + id: String, + name: String, + version: String, + description: String, + binaryName: String, + capabilities: [MassPanicCapability], + icon: Option, +} + +const config: MassPanicModuleConfig = #{ + id: "mass-panic", + name: "Mass Panic", + version: "2.1.0", + description: "Organisation-scale batch scanning — assemblyline + BLAKE3 + imaging + temporal + verisim", + binaryName: "panic-attack", + icon: Some("zap-off"), + capabilities: [ + AssemblylineScanning, + IncrementalBlake3, + VerisimDBPersistence, + DeltaReporting, + NotificationPipeline, + RepoDiscovery, + CacheManagement, + SystemImaging, + TemporalNavigation, + ], +}; + +fn hasCapability(cap: MassPanicCapability) -> Bool { + contains(config.capabilities, cap) +} + +fn capabilityLabel(cap: MassPanicCapability) -> String { + match cap { + AssemblylineScanning => "Assemblyline Scanning (rayon parallelism)", + IncrementalBlake3 => "Incremental BLAKE3 Fingerprinting", + VerisimDBPersistence => "VerisimDB Octad Persistence", + DeltaReporting => "Delta Reporting (diff between runs)", + NotificationPipeline => "Notification Pipeline (markdown + GitHub)", + RepoDiscovery => "Repository Discovery (.git detection)", + CacheManagement => "Fingerprint Cache Management", + SystemImaging => "System Health Imaging (fNIRS-style spatial risk map)", + TemporalNavigation => "Temporal Navigation (time-series diff + trend detection)", + } +} diff --git a/migration/modules/PanicAttackModule.affine b/migration/modules/PanicAttackModule.affine new file mode 100644 index 0000000..44187c6 --- /dev/null +++ b/migration/modules/PanicAttackModule.affine @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// PanicAttackModule.affine — capability declarations for the stress +// testing and weak point analysis panel. +// +// Translation of src/modules/PanicAttackModule.res (63 LoC). Same shape. +// +// Refs: standards#279, standards#252. + +module PanicAttackModule; + +use prelude::{Option, Some, None, contains}; + +type PanicAttackCapability = + | StaticAnalysis + | StressTesting + | BugSignatureDetection + | ReportGeneration + | ReportComparison + | BatchScanning + | SarifExport + | EventChainExport + +type PanicAttackModuleConfig = { + id: String, + name: String, + version: String, + description: String, + binaryName: String, + capabilities: [PanicAttackCapability], + icon: Option, +} + +const config: PanicAttackModuleConfig = #{ + id: "panic-attack", + name: "panic-attack", + version: "2.0.0", + description: "Universal stress testing and logic-based bug signature detection", + binaryName: "panic-attack", + icon: Some("zap"), + capabilities: [ + StaticAnalysis, + StressTesting, + BugSignatureDetection, + ReportGeneration, + ReportComparison, + BatchScanning, + SarifExport, + EventChainExport, + ], +}; + +fn hasCapability(cap: PanicAttackCapability) -> Bool { + contains(config.capabilities, cap) +} + +fn capabilityLabel(cap: PanicAttackCapability) -> String { + match cap { + StaticAnalysis => "Static Analysis (assail)", + StressTesting => "Stress Testing (attack/assault)", + BugSignatureDetection => "Bug Signature Detection (kanren)", + ReportGeneration => "Report Generation (JSON/YAML/SARIF)", + ReportComparison => "Report Comparison (diff)", + BatchScanning => "Batch Scanning (assemblyline)", + SarifExport => "SARIF Export (GitHub Security)", + EventChainExport => "Event Chain Export (PanLL)", + } +} diff --git a/migration/modules/PlazaModule.affine b/migration/modules/PlazaModule.affine new file mode 100644 index 0000000..bbc3fc1 --- /dev/null +++ b/migration/modules/PlazaModule.affine @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// PlazaModule.affine — capability registration for the PMPL licensing +// adoption and governance panel. +// +// Translation of src/modules/PlazaModule.res (79 LoC). Same shape. +// +// Refs: standards#279, standards#252. + +module PlazaModule; + +use prelude::{Option, Some, None, contains}; + +type PlazaCapability = + | AdoptionDashboard + | ComplianceAudit + | ProvenanceVerification + | CompatibilityChecker + | EthicalUseGuide + | GovernanceView + | AdoptionWizard + +type PlazaModuleConfig = { + id: String, + name: String, + version: String, + description: String, + capabilities: [PlazaCapability], + icon: Option, +} + +const config: PlazaModuleConfig = #{ + id: "plaza", + name: "Palimpsest Plaza", + version: "0.1.0", + description: "PMPL license adoption, compliance, and governance hub for the FOSS community", + capabilities: [ + AdoptionDashboard, + ComplianceAudit, + ProvenanceVerification, + CompatibilityChecker, + EthicalUseGuide, + GovernanceView, + AdoptionWizard, + ], + icon: Some("scroll"), +}; + +fn hasCapability(cap: PlazaCapability) -> Bool { + contains(config.capabilities, cap) +} + +fn capabilityLabel(cap: PlazaCapability) -> String { + match cap { + AdoptionDashboard => "Adoption Dashboard", + ComplianceAudit => "Compliance Audit", + ProvenanceVerification => "Provenance Verification", + CompatibilityChecker => "Compatibility Checker", + EthicalUseGuide => "Ethical Use Guide", + GovernanceView => "Governance", + AdoptionWizard => "Adopt PMPL", + } +} diff --git a/migration/modules/STATUS.md b/migration/modules/STATUS.md new file mode 100644 index 0000000..6d16c49 --- /dev/null +++ b/migration/modules/STATUS.md @@ -0,0 +1,81 @@ + + + +# `migration/modules/` parity status + +Snapshot of the panll `src/modules/` ReScript → AffineScript port (Mode A — compiles). Filed 2026-05-31 as the first compilable migration batch for panll's STEP 8 megaport (standards#279). + +## Parity table + +| .affine file | `affinescript check` | Source .res LoC | Notes | +|---|---|---|---| +| `ServiceEndpoints.affine` | ✅ passes | 39 | Pure constants. | +| `TsdmModule.affine` | ✅ passes | 57 | Capability sum + config record + helpers. | +| `TangleVizModule.affine` | ✅ passes | 57 | Same shape. | +| `LanguageForgeModule.affine` | ✅ passes | 60 | Same shape. | +| `PanicAttackModule.affine` | ✅ passes | 63 | Same shape. | +| `FarmModule.affine` | ✅ passes | 66 | Same shape + manifestPath field. | +| `MassPanicModule.affine` | ✅ passes | 66 | Same shape + binaryName field. | +| `VerificationDashboardModule.affine` | ✅ passes | 67 | Same shape. | +| `SpecBrowserModule.affine` | ✅ passes | 68 | Same shape. | +| `PlazaModule.affine` | ✅ passes | 79 | Same shape. | +| `CloudGuardModule.affine` | ✅ passes | 93 | Same shape + capabilityDescription helper. | + +**Score (2026-05-31): 11 / 11 compile.** Total LoC: 715 lines of source `.res` ported. + +## What shape this batch was + +All 11 files share a single mechanical pattern: + +``` +type xxxCapability = | A | B | ... +type xxxModuleConfig = { id: ..., name: ..., capabilities: ..., icon: ... } +let config: xxxModuleConfig = { ... } +let hasCapability = (cap) => config.capabilities->Array.includes(cap) +let capabilityLabel = (cap) => switch cap { | A => "...", | B => "..." } +``` + +Mapping to AffineScript: +- `type x = | A | B` — unchanged shape (semicolons added) +- `type t = { field: T, ... }` — unchanged (no trailing comma) +- `option` → `Option` +- `array` → `[T]` +- `let config = { ... }` → `const config: T = #{ ... };` (AS records need `#{...}`) +- `let f = (x: T): U => body` → `fn f(x: T) -> U { body }` +- `arr->Array.includes(x)` → `contains(arr, x)` (prelude::contains) +- `switch x { | A => "..." }` → `match x { A => "...", }` (no leading `|`, comma-separated arms, no `=>` change) + +## What this PR is NOT + +This does **not** replace any `src/modules/*.res` file in the build. The .res files still own the runtime contract — they compile to `src/modules/*.res.mjs` via the root `rescript.json`, which the rest of panll imports. Replacement requires: + +1. AffineScript → ESM codegen for these modules. +2. Migration of (or compatibility shim for) the existing consumers — every place that does `open FarmModule`, `let cap = TsdmModule.config.capabilities`, etc. + +Both are separate slices, tracked under standards#279 STEP 8. + +## What this PR IS + +The 11 `.affine` files are the **verified-correct future shape**. When AS gains source-to-ESM codegen (Deno target already supports this for stdlib; module-tree support is the gap), promoting these 11 files to in-build status becomes a one-PR cutover instead of an 11-PR rewrite — the design risk is already discharged here. + +## What blocked the *other* panll subsystems + +These 11 module files were the cleanest port surface in panll. Most of the other 715 remaining `.res` files block on: + +| Blocker | Affected subsystem | Effect | +|---|---|---| +| **TEA framework bindings** (Tea_App, Tea_Cmd, Tea_Html, Tea_Sub, Tea_Vdom, ...) | All of `src/components/` (126), `src/update/` (89), `src/view/`, `src/App.res`, `src/View.res` | Components / view / update use `Tea_*` modules. Need AffineScript-side TEA bindings before port. | +| **Gossamer IPC FFI** | `src/subscriptions/GossamerEvents.res`, `clade-portal/`, `src/RuntimeBridge*` | Need AS Gossamer IPC bindings. | +| **ReScript JSX** | `src/components/*` | View files use JSX. AS has a different view story; need port plan. | +| **`Js.*` interop** | `src/storage/Storage.res`, `src/SubscriptionsFixed.res`, `clade-portal/src/CladeCmd.res` (`JsExn`) | Need `use deno::{...}` equivalents or carve-outs. | + +## Replacement of `src/modules/*.res` + +Once .affine → .mjs codegen lands for non-stdlib modules, the swap is mechanical (per file): + +1. Compile `.affine` to `.res.mjs`-equivalent. +2. Verify consumer modules see identical export names (`config`, `hasCapability`, `capabilityLabel`, `capabilityDescription` where present). +3. Delete the `.res` source. +4. Run tests. + +The current batch sets up step 1 input (each file passes `affinescript check`); step 2 (consumer compat) needs naming-convention verification — capability sum names are PascalCase on both sides (`FarmCapability`), but the underlying ReScript convention used camelCase `farmCapability`. Consumers either pattern-match on the constructors (no problem) or use the type-name as a type annotation (might need a rename pass; tracked in STATUS as the only known consumer-port wart). diff --git a/migration/modules/ServiceEndpoints.affine b/migration/modules/ServiceEndpoints.affine new file mode 100644 index 0000000..f068971 --- /dev/null +++ b/migration/modules/ServiceEndpoints.affine @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// ServiceEndpoints.affine — centralised default URLs for all backend services. +// +// Translation of src/modules/ServiceEndpoints.res (39 LoC, 9 const decls, +// 0 functions). Pure constants — no FFI, no Tea_*, no Promise / Pixi / +// Gossamer. The cleanest possible Mode-A AffineScript port surface in +// panll today. +// +// Translation choices: +// `let x = "..."` → `const x: String = "...";` (semicolons + explicit +// type — AffineScript requires both at module-top-level constants). +// The `panic-attack:allow insecure-protocol` annotation is preserved as +// a comment; the .affine surface inherits the same scanner-policy +// semantics from the file's existence under migration/modules/. +// +// What this PR is NOT +// It does NOT replace src/modules/ServiceEndpoints.res in the build. +// The .res still owns the runtime contract (it compiles to +// src/modules/ServiceEndpoints.res.mjs, which consumers import). +// Replacement requires .affine→.mjs codegen + consumer migration — +// separate work, tracked under standards#279 STEP 8. +// +// Refs: standards#279 (megaport step), standards#252 (campaign umbrella). +// +// panic-attack:allow insecure-protocol — all URLs are localhost/loopback +// development endpoints. Local services do not run TLS. Production +// deployments override these via environment variables or config files. + +module ServiceEndpoints; + +/// VeriSimDB octad multimodal database. +const verisim: String = "http://localhost:8080/api/v1"; + +/// QuandleDB algebraic query database. +const quandledb: String = "http://localhost:8081/api/v1"; + +/// LithoGlyph graph pattern database. +const lithoglyph: String = "http://localhost:8082/api/v1"; + +/// BoJ (Bundle of Joy) cartridge gateway server. +const bojServer: String = "http://localhost:7700"; + +/// ECHIDNA proof assistant / multi-solver dispatch. +const echidna: String = "http://localhost:9000/api/v1"; + +/// Gitbot-Fleet Axum dashboard API. +const fleet: String = "http://localhost:8090/api/v1"; + +/// Multiplayer Monitor WebSocket server. +const multiplayerMonitor: String = "ws://localhost:4000/socket/websocket"; + +/// Game Preview Vite dev server. +const gamePreviewDev: String = "http://localhost:8080"; + +/// Migration backend (VeriSimDB-backed). +const migrationBackend: String = "http://localhost:8080/api/v1"; diff --git a/migration/modules/SpecBrowserModule.affine b/migration/modules/SpecBrowserModule.affine new file mode 100644 index 0000000..26d168c --- /dev/null +++ b/migration/modules/SpecBrowserModule.affine @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// SpecBrowserModule.affine — capability registration for the language +// spec browser. +// +// Translation of src/modules/SpecBrowserModule.res (68 LoC). Same shape. +// +// Refs: standards#279, standards#252. + +module SpecBrowserModule; + +use prelude::{Option, Some, None, contains}; + +type SpecBrowserCapability = + | TaxonomyOverview + | SpecComparison + | GrammarViewer + | TypingRulesViewer + | VerificationStatus + +type SpecBrowserModuleConfig = { + id: String, + name: String, + version: String, + description: String, + capabilities: [SpecBrowserCapability], + icon: Option, +} + +const config: SpecBrowserModuleConfig = #{ + id: "spec-browser", + name: "Spec Browser", + version: "0.1.0", + description: "Browse all 16 language specs, grammars, typing rules — side-by-side comparison and taxonomy completeness", + capabilities: [ + TaxonomyOverview, + SpecComparison, + GrammarViewer, + TypingRulesViewer, + VerificationStatus, + ], + icon: Some("book-open"), +}; + +fn hasCapability(cap: SpecBrowserCapability) -> Bool { + contains(config.capabilities, cap) +} + +fn capabilityLabel(cap: SpecBrowserCapability) -> String { + match cap { + TaxonomyOverview => "Taxonomy Overview", + SpecComparison => "Spec Comparison", + GrammarViewer => "Grammar Viewer", + TypingRulesViewer => "Typing Rules Viewer", + VerificationStatus => "Verification Status", + } +} diff --git a/migration/modules/TangleVizModule.affine b/migration/modules/TangleVizModule.affine new file mode 100644 index 0000000..b66b82b --- /dev/null +++ b/migration/modules/TangleVizModule.affine @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// TangleVizModule.affine — capability registration for the Tangle +// topology panel. +// +// Translation of src/modules/TangleVizModule.res (57 LoC). Same shape. +// +// Refs: standards#279, standards#252. + +module TangleVizModule; + +use prelude::{Option, Some, None, contains}; + +type TangleVizCapability = + | BraidVisualization + | InvariantComputation + | SourceParsing + +type TangleVizModuleConfig = { + id: String, + name: String, + version: String, + description: String, + capabilities: [TangleVizCapability], + icon: Option, +} + +const config: TangleVizModuleConfig = #{ + id: "tangle-viz", + name: "Tangle Viz", + version: "0.1.0", + description: "Topological programming visualizer — braid diagrams, knot invariants, Tangle source parsing", + capabilities: [BraidVisualization, InvariantComputation, SourceParsing], + icon: Some("knot"), +}; + +fn hasCapability(cap: TangleVizCapability) -> Bool { + contains(config.capabilities, cap) +} + +fn capabilityLabel(cap: TangleVizCapability) -> String { + match cap { + BraidVisualization => "Braid Visualization", + InvariantComputation => "Invariant Computation", + SourceParsing => "Source Parsing", + } +} diff --git a/migration/modules/TsdmModule.affine b/migration/modules/TsdmModule.affine new file mode 100644 index 0000000..4baf38d --- /dev/null +++ b/migration/modules/TsdmModule.affine @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// TsdmModule.affine — capability declarations for the Triaxial Software +// Development Methodology directive panel. +// +// Translation of src/modules/TsdmModule.res (57 LoC). Module-shape: a +// capability sum, a config record, the config value, and two helpers +// (hasCapability + capabilityLabel). All purely functional — no Tea_/ +// Pixi / Gossamer / Promise / FFI surface — so this is one of the +// cleaner Mode-A ports panll has. +// +// Translation choices: +// `type x = | A | B` → unchanged shape (semicolons added) +// `type t = { f: T, ... }` → unchanged + closing `}` no comma +// `option` → `Option` (prelude type) +// `array` → `[T]` +// `{ field: value, ... }` → `#{ field: value, ... }` (AS +// record-literal syntax; bare `{...}` is a block). +// `Array.includes(arr, x)` → `contains(arr, x)` (prelude::contains). +// `switch cap { ... }` → `match cap { ... }` with `=>` arms +// and commas, no leading `|`. +// +// What this PR is NOT +// Does NOT replace src/modules/TsdmModule.res in the build. The .res +// still owns the runtime contract. Replacement requires .affine→.mjs +// codegen + consumer migration. See migration/modules/STATUS.md. +// +// Refs: standards#279 (megaport step), standards#252 (campaign umbrella). + +module TsdmModule; + +use prelude::{Option, Some, None, contains}; + +type TsdmCapability = + | AxisReordering + | TierCustomisation + | CleanupConfiguration + | WorkItemAggregation + | DirectivePersistence + | DirectiveLocking + | ConsumerBroadcast + +type TsdmModuleConfig = { + id: String, + name: String, + version: String, + description: String, + capabilities: [TsdmCapability], + icon: Option, +} + +const config: TsdmModuleConfig = #{ + id: "tsdm", + name: "TSDM", + version: "1.0.0", + description: "Triaxial Software Development Methodology — directive panel for priority ordering across all panels", + icon: Some("compass"), + capabilities: [ + AxisReordering, + TierCustomisation, + CleanupConfiguration, + WorkItemAggregation, + DirectivePersistence, + DirectiveLocking, + ConsumerBroadcast, + ], +}; + +fn hasCapability(cap: TsdmCapability) -> Bool { + contains(config.capabilities, cap) +} + +fn capabilityLabel(cap: TsdmCapability) -> String { + match cap { + AxisReordering => "Axis Reordering (Scope, Maintenance, Audit)", + TierCustomisation => "Tier Customisation (priority within each axis)", + CleanupConfiguration => "Cleanup/Finish-Off Configuration", + WorkItemAggregation => "Work Item Aggregation (from consumer panels)", + DirectivePersistence => "Directive Persistence (localStorage + verisim)", + DirectiveLocking => "Directive Locking (prevent mid-session changes)", + ConsumerBroadcast => "Consumer Broadcast (notify panels of ordering changes)", + } +} diff --git a/migration/modules/VerificationDashboardModule.affine b/migration/modules/VerificationDashboardModule.affine new file mode 100644 index 0000000..0f87ccc --- /dev/null +++ b/migration/modules/VerificationDashboardModule.affine @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +// Copyright (c) 2026 Jonathan D.A. Jewell +// +// VerificationDashboardModule.affine — capability registration for the +// verification panel. +// +// Translation of src/modules/VerificationDashboardModule.res (67 LoC). +// Same shape. +// +// Refs: standards#279, standards#252. + +module VerificationDashboardModule; + +use prelude::{Option, Some, None, contains}; + +type VerificationDashboardCapability = + | VerificationSummary + | LanguageBreakdown + | ProofTracking + | BenchmarkResults + | FuzzingReport + +type VerificationDashboardModuleConfig = { + id: String, + name: String, + version: String, + description: String, + capabilities: [VerificationDashboardCapability], + icon: Option, +} + +const config: VerificationDashboardModuleConfig = #{ + id: "verification-dashboard", + name: "Verification Dashboard", + version: "0.1.0", + description: "Proof, test, benchmark, and fuzzing status across all nextgen-languages repos", + capabilities: [ + VerificationSummary, + LanguageBreakdown, + ProofTracking, + BenchmarkResults, + FuzzingReport, + ], + icon: Some("check-circle"), +}; + +fn hasCapability(cap: VerificationDashboardCapability) -> Bool { + contains(config.capabilities, cap) +} + +fn capabilityLabel(cap: VerificationDashboardCapability) -> String { + match cap { + VerificationSummary => "Verification Summary", + LanguageBreakdown => "Language Breakdown", + ProofTracking => "Proof Tracking", + BenchmarkResults => "Benchmark Results", + FuzzingReport => "Fuzzing Report", + } +}