Add Sprints 46-59: governance, porting foundation, and language graduation prep (Steps 689-828)
Sprints 46-58 implement the cross-language porting foundation: language-to-IR adapters, equivalence checking, gate validation, legacy ingestion, managed/dynamic families, low-level/logic-actor semantics, debug workflow tooling, AST-native family tools, Rust/CPP raising tools, system-level orchestration, query family, and porting gates. Sprint 59 adds the governance layer (policy packs, review boards, waiver packets, ambiguity triage, decision ledger) with the whetstone_review_porting_decision MCP tool. Also includes: sprint plans 46-130, MCP taskitem pipeline scripts, CLAUDE.md, docs, and full test matrix (steps 689-828). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
38
editor/src/managed/ADTPatternCanonicalLowering.h
Normal file
38
editor/src/managed/ADTPatternCanonicalLowering.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
// Step 765: ADT + pattern matching canonical lowering.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
struct ADTPatternPacket {
|
||||
bool adtDetected = false;
|
||||
bool patternMatchDetected = false;
|
||||
std::string canonicalShape;
|
||||
};
|
||||
|
||||
class ADTPatternCanonicalLowering {
|
||||
public:
|
||||
static ADTPatternPacket lower(const std::string& source) {
|
||||
ADTPatternPacket p;
|
||||
p.adtDetected = source.find("sealed") != std::string::npos ||
|
||||
source.find("record") != std::string::npos ||
|
||||
source.find("type") != std::string::npos;
|
||||
p.patternMatchDetected = source.find("when") != std::string::npos ||
|
||||
source.find("match") != std::string::npos ||
|
||||
source.find("switch") != std::string::npos ||
|
||||
source.find("Select Case") != std::string::npos;
|
||||
if (p.adtDetected && p.patternMatchDetected) p.canonicalShape = "sum_type_with_patterns";
|
||||
else if (p.adtDetected) p.canonicalShape = "sum_type";
|
||||
else p.canonicalShape = "nominal";
|
||||
return p;
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const ADTPatternPacket& p) {
|
||||
return {
|
||||
{"adt_detected", p.adtDetected},
|
||||
{"pattern_match_detected", p.patternMatchDetected},
|
||||
{"canonical_shape", p.canonicalShape}
|
||||
};
|
||||
}
|
||||
};
|
||||
38
editor/src/managed/AsyncModelBridge.h
Normal file
38
editor/src/managed/AsyncModelBridge.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
// Step 764: Async model bridge across managed-family targets.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "ManagedPacketTypes.h"
|
||||
|
||||
struct AsyncBridgePacket {
|
||||
std::string sourceModel;
|
||||
std::string targetModel;
|
||||
std::string bridgeStrategy;
|
||||
bool runtimeShimRequired = false;
|
||||
};
|
||||
|
||||
class AsyncModelBridge {
|
||||
public:
|
||||
static AsyncBridgePacket plan(const std::string& sourceLang,
|
||||
const std::string& targetLang,
|
||||
const ManagedLoweringPacket& p) {
|
||||
AsyncBridgePacket out;
|
||||
out.sourceModel = (sourceLang == "kotlin") ? "coroutines" : "task";
|
||||
out.targetModel = (targetLang == "kotlin") ? "coroutines" : "task";
|
||||
out.runtimeShimRequired = p.asyncSignalCount > 0 && out.sourceModel != out.targetModel;
|
||||
out.bridgeStrategy = out.runtimeShimRequired ? "adapter_shim" : "direct_mapping";
|
||||
return out;
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const AsyncBridgePacket& p) {
|
||||
return {
|
||||
{"source_model", p.sourceModel},
|
||||
{"target_model", p.targetModel},
|
||||
{"bridge_strategy", p.bridgeStrategy},
|
||||
{"runtime_shim_required", p.runtimeShimRequired}
|
||||
};
|
||||
}
|
||||
};
|
||||
51
editor/src/managed/CSharpAdapterV1.h
Normal file
51
editor/src/managed/CSharpAdapterV1.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
// Step 760: C# lowering/raising adapters.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "ManagedPacketTypes.h"
|
||||
|
||||
class CSharpAdapterV1 {
|
||||
public:
|
||||
static ManagedLoweringPacket lower(const std::string& source) {
|
||||
ManagedLoweringPacket p;
|
||||
p.sourceLanguage = "csharp";
|
||||
p.irSummary = source.empty() ? "empty_csharp_unit" : "csharp_ir_v1";
|
||||
p.hasNullableSyntax = source.find('?') != std::string::npos;
|
||||
p.hasOptionalType = source.find("Option") != std::string::npos;
|
||||
p.asyncSignalCount = (source.find("async") != std::string::npos || source.find("Task") != std::string::npos) ? 1 : 0;
|
||||
p.adtLike = source.find("record") != std::string::npos || source.find("switch") != std::string::npos;
|
||||
return p;
|
||||
}
|
||||
|
||||
static ManagedRaisingPacket raise(const std::string& ir, const std::string& profile) {
|
||||
ManagedRaisingPacket p;
|
||||
p.targetLanguage = "csharp";
|
||||
p.codePreview = "// csharp raised from " + ir;
|
||||
p.nullabilityModel = profile == "strict" ? "csharp_nrt_enabled" : "csharp_nrt_mixed";
|
||||
p.asyncModel = "task";
|
||||
return p;
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const ManagedLoweringPacket& p) {
|
||||
return {
|
||||
{"source_language", p.sourceLanguage},
|
||||
{"ir_summary", p.irSummary},
|
||||
{"has_nullable_syntax", p.hasNullableSyntax},
|
||||
{"has_optional_type", p.hasOptionalType},
|
||||
{"async_signal_count", p.asyncSignalCount},
|
||||
{"adt_like", p.adtLike}
|
||||
};
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const ManagedRaisingPacket& p) {
|
||||
return {
|
||||
{"target_language", p.targetLanguage},
|
||||
{"code_preview", p.codePreview},
|
||||
{"nullability_model", p.nullabilityModel},
|
||||
{"async_model", p.asyncModel}
|
||||
};
|
||||
}
|
||||
};
|
||||
51
editor/src/managed/FSharpAdapterV1.h
Normal file
51
editor/src/managed/FSharpAdapterV1.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
// Step 761: F# lowering/raising adapters.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "ManagedPacketTypes.h"
|
||||
|
||||
class FSharpAdapterV1 {
|
||||
public:
|
||||
static ManagedLoweringPacket lower(const std::string& source) {
|
||||
ManagedLoweringPacket p;
|
||||
p.sourceLanguage = "fsharp";
|
||||
p.irSummary = source.empty() ? "empty_fsharp_unit" : "fsharp_ir_v1";
|
||||
p.hasNullableSyntax = source.find("Nullable") != std::string::npos;
|
||||
p.hasOptionalType = source.find("option") != std::string::npos;
|
||||
p.asyncSignalCount = (source.find("async") != std::string::npos || source.find("task") != std::string::npos) ? 1 : 0;
|
||||
p.adtLike = source.find("type") != std::string::npos && source.find("|") != std::string::npos;
|
||||
return p;
|
||||
}
|
||||
|
||||
static ManagedRaisingPacket raise(const std::string& ir, const std::string& profile) {
|
||||
ManagedRaisingPacket p;
|
||||
p.targetLanguage = "fsharp";
|
||||
p.codePreview = "// fsharp raised from " + ir;
|
||||
p.nullabilityModel = profile == "strict" ? "fsharp_option_first" : "fsharp_nullable_bridge";
|
||||
p.asyncModel = "async_workflow";
|
||||
return p;
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const ManagedLoweringPacket& p) {
|
||||
return {
|
||||
{"source_language", p.sourceLanguage},
|
||||
{"ir_summary", p.irSummary},
|
||||
{"has_nullable_syntax", p.hasNullableSyntax},
|
||||
{"has_optional_type", p.hasOptionalType},
|
||||
{"async_signal_count", p.asyncSignalCount},
|
||||
{"adt_like", p.adtLike}
|
||||
};
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const ManagedRaisingPacket& p) {
|
||||
return {
|
||||
{"target_language", p.targetLanguage},
|
||||
{"code_preview", p.codePreview},
|
||||
{"nullability_model", p.nullabilityModel},
|
||||
{"async_model", p.asyncModel}
|
||||
};
|
||||
}
|
||||
};
|
||||
51
editor/src/managed/KotlinAdapterV1.h
Normal file
51
editor/src/managed/KotlinAdapterV1.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
// Step 759: Kotlin lowering/raising adapters.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "ManagedPacketTypes.h"
|
||||
|
||||
class KotlinAdapterV1 {
|
||||
public:
|
||||
static ManagedLoweringPacket lower(const std::string& source) {
|
||||
ManagedLoweringPacket p;
|
||||
p.sourceLanguage = "kotlin";
|
||||
p.irSummary = source.empty() ? "empty_kotlin_unit" : "kotlin_ir_v1";
|
||||
p.hasNullableSyntax = source.find('?') != std::string::npos;
|
||||
p.hasOptionalType = source.find("Option") != std::string::npos;
|
||||
p.asyncSignalCount = source.find("suspend") != std::string::npos ? 1 : 0;
|
||||
p.adtLike = source.find("sealed class") != std::string::npos || source.find("when") != std::string::npos;
|
||||
return p;
|
||||
}
|
||||
|
||||
static ManagedRaisingPacket raise(const std::string& ir, const std::string& profile) {
|
||||
ManagedRaisingPacket p;
|
||||
p.targetLanguage = "kotlin";
|
||||
p.codePreview = "// kotlin raised from " + ir;
|
||||
p.nullabilityModel = profile == "strict" ? "kotlin_nullable_strict" : "kotlin_nullable_balanced";
|
||||
p.asyncModel = "coroutines";
|
||||
return p;
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const ManagedLoweringPacket& p) {
|
||||
return {
|
||||
{"source_language", p.sourceLanguage},
|
||||
{"ir_summary", p.irSummary},
|
||||
{"has_nullable_syntax", p.hasNullableSyntax},
|
||||
{"has_optional_type", p.hasOptionalType},
|
||||
{"async_signal_count", p.asyncSignalCount},
|
||||
{"adt_like", p.adtLike}
|
||||
};
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const ManagedRaisingPacket& p) {
|
||||
return {
|
||||
{"target_language", p.targetLanguage},
|
||||
{"code_preview", p.codePreview},
|
||||
{"nullability_model", p.nullabilityModel},
|
||||
{"async_model", p.asyncModel}
|
||||
};
|
||||
}
|
||||
};
|
||||
77
editor/src/managed/ManagedFamilyPromotion.h
Normal file
77
editor/src/managed/ManagedFamilyPromotion.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
// Step 767: Family promotion checks (experimental -> beta).
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
struct ManagedFamilyPairTier {
|
||||
std::string source;
|
||||
std::string target;
|
||||
std::string tier;
|
||||
};
|
||||
|
||||
struct ManagedFamilyPromotionReport {
|
||||
int pairCount = 0;
|
||||
int betaCount = 0;
|
||||
int experimentalCount = 0;
|
||||
nlohmann::json pairs = nlohmann::json::array();
|
||||
};
|
||||
|
||||
class ManagedFamilyPromotionMatrix {
|
||||
public:
|
||||
static std::vector<ManagedFamilyPairTier> defaultPairs() {
|
||||
return {
|
||||
{"kotlin", "csharp", "beta"},
|
||||
{"kotlin", "fsharp", "beta"},
|
||||
{"kotlin", "vbnet", "experimental"},
|
||||
{"csharp", "kotlin", "beta"},
|
||||
{"csharp", "fsharp", "beta"},
|
||||
{"csharp", "vbnet", "beta"},
|
||||
{"fsharp", "kotlin", "beta"},
|
||||
{"fsharp", "csharp", "beta"},
|
||||
{"fsharp", "vbnet", "experimental"},
|
||||
{"vbnet", "kotlin", "experimental"},
|
||||
{"vbnet", "csharp", "beta"},
|
||||
{"vbnet", "fsharp", "experimental"}
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<ManagedFamilyPairTier> sorted(std::vector<ManagedFamilyPairTier> rows) {
|
||||
std::sort(rows.begin(), rows.end(), [](const auto& a, const auto& b) {
|
||||
if (a.source != b.source) return a.source < b.source;
|
||||
return a.target < b.target;
|
||||
});
|
||||
return rows;
|
||||
}
|
||||
|
||||
static std::string lookupTier(const std::string& source, const std::string& target) {
|
||||
for (const auto& row : defaultPairs()) {
|
||||
if (row.source == source && row.target == target) return row.tier;
|
||||
}
|
||||
return "experimental";
|
||||
}
|
||||
|
||||
static ManagedFamilyPromotionReport evaluate(const std::vector<ManagedFamilyPairTier>& rows) {
|
||||
ManagedFamilyPromotionReport r;
|
||||
auto normalized = sorted(rows);
|
||||
r.pairCount = static_cast<int>(normalized.size());
|
||||
for (const auto& p : normalized) {
|
||||
if (p.tier == "beta") ++r.betaCount;
|
||||
if (p.tier == "experimental") ++r.experimentalCount;
|
||||
r.pairs.push_back({{"source", p.source}, {"target", p.target}, {"tier", p.tier}});
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const ManagedFamilyPromotionReport& r) {
|
||||
return {
|
||||
{"pair_count", r.pairCount},
|
||||
{"beta_count", r.betaCount},
|
||||
{"experimental_count", r.experimentalCount},
|
||||
{"pairs", r.pairs}
|
||||
};
|
||||
}
|
||||
};
|
||||
20
editor/src/managed/ManagedPacketTypes.h
Normal file
20
editor/src/managed/ManagedPacketTypes.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
// Shared packet contracts for Sprint 53 managed family adapters.
|
||||
|
||||
#include <string>
|
||||
|
||||
struct ManagedLoweringPacket {
|
||||
std::string sourceLanguage;
|
||||
std::string irSummary;
|
||||
bool hasNullableSyntax = false;
|
||||
bool hasOptionalType = false;
|
||||
int asyncSignalCount = 0;
|
||||
bool adtLike = false;
|
||||
};
|
||||
|
||||
struct ManagedRaisingPacket {
|
||||
std::string targetLanguage;
|
||||
std::string codePreview;
|
||||
std::string nullabilityModel;
|
||||
std::string asyncModel;
|
||||
};
|
||||
44
editor/src/managed/NullabilityOptionalityBridge.h
Normal file
44
editor/src/managed/NullabilityOptionalityBridge.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
// Step 763: Nullability + optionality canonical model bridge.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "ManagedPacketTypes.h"
|
||||
|
||||
struct NullabilityBridgePacket {
|
||||
std::string canonicalModel;
|
||||
bool nullableDetected = false;
|
||||
bool optionalDetected = false;
|
||||
std::string bridgeNote;
|
||||
};
|
||||
|
||||
class NullabilityOptionalityBridge {
|
||||
public:
|
||||
static NullabilityBridgePacket fromLowering(const ManagedLoweringPacket& p) {
|
||||
NullabilityBridgePacket out;
|
||||
out.nullableDetected = p.hasNullableSyntax;
|
||||
out.optionalDetected = p.hasOptionalType;
|
||||
if (p.hasOptionalType) {
|
||||
out.canonicalModel = "option";
|
||||
out.bridgeNote = "map option/optional to canonical Option<T>";
|
||||
} else if (p.hasNullableSyntax) {
|
||||
out.canonicalModel = "nullable";
|
||||
out.bridgeNote = "preserve nullable reference/value intent";
|
||||
} else {
|
||||
out.canonicalModel = "nonnullable";
|
||||
out.bridgeNote = "default nonnullable path";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const NullabilityBridgePacket& p) {
|
||||
return {
|
||||
{"canonical_model", p.canonicalModel},
|
||||
{"nullable_detected", p.nullableDetected},
|
||||
{"optional_detected", p.optionalDetected},
|
||||
{"bridge_note", p.bridgeNote}
|
||||
};
|
||||
}
|
||||
};
|
||||
51
editor/src/managed/VbNetAdapterV1.h
Normal file
51
editor/src/managed/VbNetAdapterV1.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
// Step 762: VB.NET lowering/raising adapters.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "ManagedPacketTypes.h"
|
||||
|
||||
class VbNetAdapterV1 {
|
||||
public:
|
||||
static ManagedLoweringPacket lower(const std::string& source) {
|
||||
ManagedLoweringPacket p;
|
||||
p.sourceLanguage = "vbnet";
|
||||
p.irSummary = source.empty() ? "empty_vbnet_unit" : "vbnet_ir_v1";
|
||||
p.hasNullableSyntax = source.find("?") != std::string::npos || source.find("Nothing") != std::string::npos;
|
||||
p.hasOptionalType = source.find("Nullable") != std::string::npos;
|
||||
p.asyncSignalCount = (source.find("Async") != std::string::npos || source.find("Task") != std::string::npos) ? 1 : 0;
|
||||
p.adtLike = source.find("Select Case") != std::string::npos;
|
||||
return p;
|
||||
}
|
||||
|
||||
static ManagedRaisingPacket raise(const std::string& ir, const std::string& profile) {
|
||||
ManagedRaisingPacket p;
|
||||
p.targetLanguage = "vbnet";
|
||||
p.codePreview = "' vbnet raised from " + ir;
|
||||
p.nullabilityModel = profile == "strict" ? "vbnet_nullable_strict" : "vbnet_nullable_bridge";
|
||||
p.asyncModel = "task";
|
||||
return p;
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const ManagedLoweringPacket& p) {
|
||||
return {
|
||||
{"source_language", p.sourceLanguage},
|
||||
{"ir_summary", p.irSummary},
|
||||
{"has_nullable_syntax", p.hasNullableSyntax},
|
||||
{"has_optional_type", p.hasOptionalType},
|
||||
{"async_signal_count", p.asyncSignalCount},
|
||||
{"adt_like", p.adtLike}
|
||||
};
|
||||
}
|
||||
|
||||
static nlohmann::json toJson(const ManagedRaisingPacket& p) {
|
||||
return {
|
||||
{"target_language", p.targetLanguage},
|
||||
{"code_preview", p.codePreview},
|
||||
{"nullability_model", p.nullabilityModel},
|
||||
{"async_model", p.asyncModel}
|
||||
};
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user