From 3902a0908e985217925a186614f58834b5f47012 Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:04:56 +0200 Subject: [PATCH 01/13] feat(franchise-factory): migrate GFF package into Genesis Engine --- franchise_factory/gff/__init__.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 franchise_factory/gff/__init__.py diff --git a/franchise_factory/gff/__init__.py b/franchise_factory/gff/__init__.py new file mode 100644 index 0000000..2f7e634 --- /dev/null +++ b/franchise_factory/gff/__init__.py @@ -0,0 +1,28 @@ +"""Genesis Franchise Factory (GFF) — Core-Paket. + +Content-Pipeline-Orchestrator des Genesis-Oekosystems. +Kanonische Spec-Quelle: specs/*.atc (AD-20..AD-43, unveraendert aus dem +Org-Archiv a-townchain-os-docs/docs/archive/monorepo-full uebernommen). + +Trennungsregel (verbindlich): GFF sitzt UEBER der Genesis Engine und ist +strikte Plattform — keinerlei Abhaengigkeit zu Genesis Chronicles. +""" + +__version__ = "0.1.0" + +from gff.artifacts import ArtifactContractError, ArtifactEnvelope, ArtifactKind, ArtifactRef +from gff.core import Franchise, FranchiseBlueprint, FranchiseStatus, GFFCore, PipelineStage +from gff.dao import FranchiseFactory as DAOFranchiseFactory +from gff.game_factory import GAME_FACTORY_GRAPH, GameFactoryGraphError, GameFactoryNode, topological_order +from gff.lifecycle import LifecycleManager, LPhase +from gff.workflows import ( + DEFAULT_WORKFLOWS, + GAME_SUBSYSTEMS, + FactoryId, + WorkflowContext, + WorkflowDefinition, + WorkflowEngine, + WorkflowError, + WorkflowRegistry, + WorkflowStage, +) From 0d0a4df2c4142aa724b2e0d845f9a4aa537e284d Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:05:07 +0200 Subject: [PATCH 02/13] feat(franchise-factory): migrate GFF core --- franchise_factory/gff/core.py | 158 ++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 franchise_factory/gff/core.py diff --git a/franchise_factory/gff/core.py b/franchise_factory/gff/core.py new file mode 100644 index 0000000..6adaadb --- /dev/null +++ b/franchise_factory/gff/core.py @@ -0,0 +1,158 @@ +"""GFF Core — Pipeline-Orchestrator (AD-20, kanonische Referenz-Implementierung). + +Portiert gff_core_ad20.atc: Franchise-Registry, 10-stufige Default-Pipeline, +Events. Der Executor ist injizierbar (Production-Integration spaeter via GCL/ATC-VM); +ohne Executor laeuft die Pipeline im ehrlichen DRY-RUN (kein Fake-Output). +""" + +from __future__ import annotations + +import hashlib +import time +from collections.abc import Callable +from dataclasses import dataclass, field +from enum import Enum + +from gff.spec_loader import FactorySpec, load_specs + + +class FranchiseStatus(Enum): + CONCEPT = "Concept" + IN_PRODUCTION = "InProduction" + TESTING = "Testing" + LIVE = "Live" + EXPANDING = "Expanding" + ARCHIVED = "Archived" + + +class PipelineStatus(Enum): + PENDING = "Pending" + IN_PROGRESS = "InProgress" + COMPLETE = "Complete" + SKIPPED = "Skipped" + + +@dataclass +class FranchiseBlueprint: + name: str + genre: str + target_audience: str = "" + world_count: int = 1 + character_count: int = 0 + quest_count: int = 0 + economy_model: str = "" + monetization: list[str] = field(default_factory=list) + platforms: list[str] = field(default_factory=list) + + +@dataclass +class Franchise: + id: str + name: str + universe: str + status: FranchiseStatus + created_at: float + blueprint: FranchiseBlueprint + factories_used: list[str] = field(default_factory=list) + progress: float = 0.0 + + +@dataclass +class PipelineStage: + name: str + factory: str + order: int + enabled: bool = True + status: PipelineStatus = PipelineStatus.PENDING + + +@dataclass +class StageResult: + success: bool + note: str = "dry-run" + + +Executor = Callable[[PipelineStage, Franchise], StageResult] + + +def _noop_executor(stage: PipelineStage, franchise: Franchise) -> StageResult: + return StageResult(success=True, note="dry-run: kein Executor injiziert") + + +def default_pipeline() -> list[PipelineStage]: + return [ + PipelineStage("Blueprint", "ip_factory", 0), + PipelineStage("World", "world_factory", 1), + PipelineStage("Character", "character_factory", 2), + PipelineStage("Lore", "lore_factory", 3), + PipelineStage("Quest", "quest_factory", 4), + PipelineStage("Asset", "ai_content_factory", 5), + PipelineStage("Game", "world_factory", 6), + PipelineStage("Testing", "analytics_factory", 7), + PipelineStage("LiveOps", "liveops_factory", 8), + PipelineStage("Merchandise", "merchandise_factory", 9), + ] + + +class GFFCore: + def __init__(self, spec_dir=None, version: str = "1.0.0"): + self.version = version + self.initialized = True + self.franchises: dict[str, Franchise] = {} + self.active_franchise: str | None = None + self.pipeline: list[PipelineStage] = default_pipeline() + self.pipeline_running = False + self.events: list[dict] = [] + self.factory_specs: dict[int, FactorySpec] = load_specs(spec_dir) if spec_dir is not None else {} + self._emit("GFFInitialized", version=version) + + def _emit(self, event: str, **data) -> None: + self.events.append({"event": event, "ts": time.time(), **data}) + + def create_franchise(self, blueprint: FranchiseBlueprint, *, now: float | None = None) -> str: + ts = time.time() if now is None else now + fid = hashlib.sha256(f"{blueprint.name}|{ts}".encode()).hexdigest()[:16] + if not blueprint.name: + raise ValueError("blueprint.name darf nicht leer sein") + self.franchises[fid] = Franchise( + id=fid, name=blueprint.name, universe=f"{blueprint.name} Universe", + status=FranchiseStatus.CONCEPT, created_at=ts, blueprint=blueprint, + factories_used=[], progress=0.0, + ) + self.active_franchise = fid + self._emit("FranchiseCreated", fid=fid, name=blueprint.name) + return fid + + def run_pipeline(self, franchise_id: str, *, executor: Executor = _noop_executor) -> bool: + if franchise_id not in self.franchises: + raise KeyError(f"Franchise {franchise_id} nicht gefunden") + if self.pipeline_running: + raise RuntimeError("Pipeline laeuft bereits (pipeline_running)") + self.pipeline_running = True + self._emit("PipelineStarted", fid=franchise_id) + try: + franchise = self.franchises[franchise_id] + for stage in sorted(self.pipeline, key=lambda s: s.order): + if not stage.enabled: + stage.status = PipelineStatus.SKIPPED + continue + stage.status = PipelineStatus.IN_PROGRESS + result = executor(stage, franchise) + if not result.success: + self._emit("StageFailed", fid=franchise_id, stage=stage.name, note=result.note) + raise RuntimeError(f"Stage {stage.name} fehlgeschlagen: {result.note}") + stage.status = PipelineStatus.COMPLETE + if stage.factory not in franchise.factories_used: + franchise.factories_used.append(stage.factory) + self._emit("StageComplete", fid=franchise_id, stage=stage.name) + done = sum(1 for s in self.pipeline if s.status == PipelineStatus.COMPLETE) + total = sum(1 for s in self.pipeline if s.enabled) + franchise.progress = round(done / total, 4) if total else 0.0 + self._emit("PipelineComplete", fid=franchise_id, progress=franchise.progress) + return True + finally: + self.pipeline_running = False + + def reset_pipeline(self) -> None: + for s in self.pipeline: + s.status = PipelineStatus.PENDING From 681914598a913b8cf3632a1be15f54aa37c41381 Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:05:18 +0200 Subject: [PATCH 03/13] feat(franchise-factory): migrate DAO component --- franchise_factory/gff/dao.py | 57 ++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 franchise_factory/gff/dao.py diff --git a/franchise_factory/gff/dao.py b/franchise_factory/gff/dao.py new file mode 100644 index 0000000..9967868 --- /dev/null +++ b/franchise_factory/gff/dao.py @@ -0,0 +1,57 @@ +"""ATC-9900 DAO-Modell (factory.atc / factory.py-Prototyp, portiert & bereinigt).""" +from __future__ import annotations +import hashlib, time +from dataclasses import dataclass, field +from enum import Enum +class FranchiseStatus(Enum): + PROPOSAL="proposal"; ACTIVE="active"; SUSPENDED="suspended"; DISSOLVED="dissolved" +class RoyaltyTier(Enum): + BRONZE=0.05; SILVER=0.04; GOLD=0.03; PLATINUM=0.02 +@dataclass +class FranchiseVault: + balance: float=0.0; total_in: float=0.0; total_out: float=0.0; transactions:list[dict]=field(default_factory=list) + def deposit(self, amount:float, from_addr:str, note:str="")->None: + if amount<0: raise ValueError("deposit: negativer Betrag") + self.balance+=amount; self.total_in+=amount + self.transactions.append({"type":"deposit","amount":amount,"from":from_addr,"note":note,"ts":time.time()}) + def withdraw(self, amount:float, to_addr:str, note:str="")->bool: + if amount>self.balance: return False + self.balance-=amount; self.total_out+=amount + self.transactions.append({"type":"withdraw","amount":amount,"to":to_addr,"note":note,"ts":time.time()}); return True +@dataclass +class Franchise: + id:str; name:str; owner:str; description:str; token_symbol:str; token_supply:float + royalty_tier:RoyaltyTier=RoyaltyTier.BRONZE; status:FranchiseStatus=FranchiseStatus.PROPOSAL + created:float=field(default_factory=time.time); members:dict[str,float]=field(default_factory=dict) + vault:FranchiseVault=field(default_factory=FranchiseVault); proposals:list[dict]=field(default_factory=list) + def add_member(self,addr:str,stake:float)->None: + if stake<0: raise ValueError("add_member: negativer Stake") + self.members[addr]=self.members.get(addr,0)+stake + def total_stake(self)->float: return sum(self.members.values()) + def voting_power(self,addr:str)->float: + total=self.total_stake(); return 0.0 if total==0 else self.members.get(addr,0)/total + def distribute_revenue(self,amount:float)->dict: + if amount<0: raise ValueError("distribute_revenue: negativer Betrag") + total=self.total_stake(); self.vault.deposit(amount,"revenue","Einnahmen") + royalty=amount*self.royalty_tier.value; net=amount-royalty + if total==0: return {"royalty":royalty,"net":net,"distribution":{}} + return {"royalty":royalty,"net":net,"distribution":{a:(s/total)*net for a,s in self.members.items()}} +class FranchiseFactory: + def __init__(self)->None: self._franchises={}; self._owner_index={} + def create(self,name,owner,description,token_symbol,token_supply=1_000_000,royalty_tier=RoyaltyTier.BRONZE): + fid=hashlib.sha256(f"{name}{owner}{time.time()}".encode()).hexdigest()[:16] + f=Franchise(fid,name,owner,description,token_symbol,token_supply,royalty_tier,FranchiseStatus.ACTIVE) + f.add_member(owner,token_supply*0.2); self._franchises[fid]=f; self._owner_index.setdefault(owner,[]).append(fid); return f + def get(self,fid): return self._franchises.get(fid) + def list_all(self,status=None): return [f for f in self._franchises.values() if status is None or f.status==status] + def by_owner(self,owner): return [self._franchises[i] for i in self._owner_index.get(owner,[]) if i in self._franchises] + def join(self,fid,member,stake): + f=self.get(fid) + if not f or f.status!=FranchiseStatus.ACTIVE or stake<0: return False + f.add_member(member,stake); f.vault.deposit(stake,member,"Beitritt"); return True + def suspend(self,fid): + f=self.get(fid) + if not f: return False + f.status=FranchiseStatus.SUSPENDED; return True + def stats(self): + return {"total":len(self._franchises),"active":sum(1 for f in self._franchises.values() if f.status==FranchiseStatus.ACTIVE),"total_vault":sum(f.vault.balance for f in self._franchises.values())} From 23905a227fbfa9768d8f70653367d657849f35c5 Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:05:28 +0200 Subject: [PATCH 04/13] feat(franchise-factory): migrate Game Factory graph --- franchise_factory/gff/game_factory.py | 75 +++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 franchise_factory/gff/game_factory.py diff --git a/franchise_factory/gff/game_factory.py b/franchise_factory/gff/game_factory.py new file mode 100644 index 0000000..0db37d7 --- /dev/null +++ b/franchise_factory/gff/game_factory.py @@ -0,0 +1,75 @@ +"""Game Factory dependency graph and fail-closed orchestration contract.""" + +from __future__ import annotations + +from dataclasses import dataclass + +from gff.artifacts import ArtifactKind, ArtifactRef + +@dataclass(frozen=True, slots=True) +class GameFactoryNode: + id: str + produces: ArtifactKind + requires: tuple[ArtifactKind, ...] = () + +GAME_FACTORY_GRAPH: tuple[GameFactoryNode, ...] = ( + GameFactoryNode("concept", ArtifactKind.GAME_BIBLE), + GameFactoryNode("world", ArtifactKind.WORLD_BIBLE, (ArtifactKind.GAME_BIBLE,)), + GameFactoryNode("lore", ArtifactKind.LORE, (ArtifactKind.WORLD_BIBLE,)), + GameFactoryNode("character", ArtifactKind.CHARACTER, (ArtifactKind.GAME_BIBLE, ArtifactKind.LORE)), + GameFactoryNode("creature", ArtifactKind.CREATURE, (ArtifactKind.WORLD_BIBLE, ArtifactKind.LORE)), + GameFactoryNode("combat", ArtifactKind.COMBAT, (ArtifactKind.GAME_BIBLE, ArtifactKind.CHARACTER, ArtifactKind.CREATURE)), + GameFactoryNode("quest", ArtifactKind.QUEST, (ArtifactKind.WORLD_BIBLE, ArtifactKind.LORE, ArtifactKind.CHARACTER)), + GameFactoryNode("level", ArtifactKind.LEVEL, (ArtifactKind.WORLD_BIBLE, ArtifactKind.QUEST, ArtifactKind.CREATURE)), + GameFactoryNode("item", ArtifactKind.ITEM, (ArtifactKind.GAME_BIBLE,)), + GameFactoryNode("weapon", ArtifactKind.WEAPON, (ArtifactKind.CHARACTER, ArtifactKind.COMBAT)), + GameFactoryNode("animation", ArtifactKind.ANIMATION, (ArtifactKind.CHARACTER, ArtifactKind.CREATURE, ArtifactKind.WEAPON)), + GameFactoryNode("audio", ArtifactKind.AUDIO, (ArtifactKind.GAME_BIBLE, ArtifactKind.WEAPON)), + GameFactoryNode("vfx", ArtifactKind.VFX, (ArtifactKind.COMBAT, ArtifactKind.WEAPON)), + GameFactoryNode("ai-npc", ArtifactKind.NPC_AI, (ArtifactKind.CHARACTER, ArtifactKind.LORE)), + GameFactoryNode("economy", ArtifactKind.ECONOMY, (ArtifactKind.GAME_BIBLE, ArtifactKind.ITEM)), + GameFactoryNode("multiplayer", ArtifactKind.MULTIPLAYER, (ArtifactKind.GAME_BIBLE, ArtifactKind.COMBAT, ArtifactKind.ECONOMY)), + GameFactoryNode("build", ArtifactKind.BUILD, (ArtifactKind.GAME_BIBLE, ArtifactKind.WORLD_BIBLE, ArtifactKind.CHARACTER, ArtifactKind.QUEST, ArtifactKind.LEVEL, ArtifactKind.ITEM, ArtifactKind.WEAPON, ArtifactKind.ANIMATION, ArtifactKind.AUDIO, ArtifactKind.VFX, ArtifactKind.NPC_AI, ArtifactKind.MULTIPLAYER)), + GameFactoryNode("testing", ArtifactKind.QA_REPORT, (ArtifactKind.BUILD, ArtifactKind.COMBAT, ArtifactKind.ECONOMY)), + GameFactoryNode("liveops", ArtifactKind.LIVEOPS_PLAN, (ArtifactKind.QA_REPORT, ArtifactKind.MULTIPLAYER, ArtifactKind.ECONOMY)), +) + +class GameFactoryGraphError(ValueError): + pass + +def validate_game_factory_graph(graph: tuple[GameFactoryNode, ...] = GAME_FACTORY_GRAPH) -> None: + produced = {node.produces for node in graph} + if len(produced) != len(graph): + raise GameFactoryGraphError("Each Game Factory node must produce a unique artifact kind") + ids = {node.id for node in graph} + if len(ids) != len(graph): + raise GameFactoryGraphError("Game Factory node ids must be unique") + for node in graph: + for requirement in node.requires: + if requirement not in produced: + raise GameFactoryGraphError(f"Node {node.id} requires {requirement}, but no producer exists") + +def topological_order(graph: tuple[GameFactoryNode, ...] = GAME_FACTORY_GRAPH) -> tuple[str, ...]: + validate_game_factory_graph(graph) + remaining = {node.produces: node for node in graph} + done: set[ArtifactKind] = set() + order: list[str] = [] + while remaining: + ready = [node for node in remaining.values() if all(req in done for req in node.requires)] + if not ready: + raise GameFactoryGraphError("Game Factory dependency cycle detected") + ready.sort(key=lambda node: node.id) + for node in ready: + order.append(node.id) + done.add(node.produces) + del remaining[node.produces] + return tuple(order) + +def dependency_refs(node: GameFactoryNode, artifacts: tuple[ArtifactRef, ...]) -> tuple[ArtifactRef, ...]: + by_kind = {artifact.kind: artifact for artifact in artifacts} + missing = [kind for kind in node.requires if kind not in by_kind] + if missing: + raise GameFactoryGraphError(f"Missing dependencies for {node.id}: {', '.join(missing)}") + return tuple(by_kind[kind] for kind in node.requires) + +validate_game_factory_graph() From 4f569cd28d6f66d10874a5ba3eb778a545174972 Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:05:33 +0200 Subject: [PATCH 05/13] feat(franchise-factory): migrate artifact contracts --- franchise_factory/gff/artifacts.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 franchise_factory/gff/artifacts.py diff --git a/franchise_factory/gff/artifacts.py b/franchise_factory/gff/artifacts.py new file mode 100644 index 0000000..f31571c --- /dev/null +++ b/franchise_factory/gff/artifacts.py @@ -0,0 +1,21 @@ +"""Typed artifact contracts for deterministic Game Factory orchestration.""" +from __future__ import annotations +from dataclasses import dataclass, field +from enum import StrEnum +from typing import Any, Mapping +class ArtifactKind(StrEnum): + GAME_BIBLE="game-bible"; WORLD_BIBLE="world-bible"; LORE="lore"; CHARACTER="character"; CREATURE="creature"; QUEST="quest"; LEVEL="level"; ITEM="item"; WEAPON="weapon"; ANIMATION="animation"; AUDIO="audio"; VFX="vfx"; COMBAT="combat"; NPC_AI="npc-ai"; ECONOMY="economy"; MULTIPLAYER="multiplayer"; BUILD="build"; QA_REPORT="qa-report"; LIVEOPS_PLAN="liveops-plan" +@dataclass(frozen=True, slots=True) +class ArtifactRef: + id:str; kind:ArtifactKind; version:str="1.0.0"; producer:str=""; content_hash:str|None=None +@dataclass(slots=True) +class ArtifactEnvelope: + ref:ArtifactRef; payload:Mapping[str,Any]=field(default_factory=dict); dependencies:tuple[ArtifactRef,...]=(); evidence:list[dict[str,Any]]=field(default_factory=list) + def add_evidence(self,kind:str,value:Any)->None: self.evidence.append({"kind":kind,"value":value}) +class ArtifactContractError(ValueError): pass +def validate_artifact(artifact:ArtifactEnvelope)->None: + if not artifact.ref.id.strip(): raise ArtifactContractError("artifact.id must not be empty") + if not artifact.ref.version.strip(): raise ArtifactContractError("artifact.version must not be empty") + if not artifact.ref.producer.strip(): raise ArtifactContractError("artifact.producer must not be empty") + for dependency in artifact.dependencies: + if not dependency.id.strip(): raise ArtifactContractError("artifact dependency id must not be empty") From bf6b6c7b2c82fc62f98bfa5c3b51b7a32ec77b35 Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:05:49 +0200 Subject: [PATCH 06/13] feat(franchise-factory): migrate workflow catalogue --- franchise_factory/gff/workflows.py | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 franchise_factory/gff/workflows.py diff --git a/franchise_factory/gff/workflows.py b/franchise_factory/gff/workflows.py new file mode 100644 index 0000000..d5dbc46 --- /dev/null +++ b/franchise_factory/gff/workflows.py @@ -0,0 +1,59 @@ +"""Declarative AI production workflows for the Genesis Franchise Factory.""" +from __future__ import annotations +from dataclasses import dataclass, field +from enum import StrEnum +from typing import Any, Callable, Mapping +class WorkflowStage(StrEnum): + INPUT="input"; ANALYZE="analyze"; PLAN="plan"; PRODUCE="produce"; QUALITY="quality"; INTEGRATE="integrate"; PUBLISH="publish"; MONITOR="monitor"; OPTIMIZE="optimize"; REPLICATE="replicate" +class FactoryId(StrEnum): + TEXT="text-content"; SOFTWARE="software"; GAME="game"; MARKETING="marketing"; BUSINESS="business"; DOCUMENT="document"; RESEARCH="research"; ECOMMERCE="e-commerce"; CUSTOMER_SERVICE="customer-service"; AUTOMATION="automation"; KNOWLEDGE="knowledge"; AGENT="agent"; FRANCHISE="franchise"; STARTUP="startup"; EDUCATION="education"; BOOK="book"; VIRTUAL_WORLD="virtual-world" +@dataclass(frozen=True, slots=True) +class WorkflowDefinition: + id:str; name:str; stages:tuple[WorkflowStage,...]; capabilities:tuple[str,...]; outputs:tuple[str,...]; description:str="" +@dataclass(slots=True) +class WorkflowContext: + workflow_id:str; payload:dict[str,Any]; artifacts:dict[str,Any]=field(default_factory=dict); evidence:list[dict[str,Any]]=field(default_factory=list); stage:WorkflowStage|None=None + def record_evidence(self,kind:str,value:Any)->None: self.evidence.append({"kind":kind,"value":value}) +Executor=Callable[[WorkflowStage,WorkflowContext],WorkflowContext] +class WorkflowError(RuntimeError): pass +class WorkflowRegistry: + def __init__(self,definitions:tuple[WorkflowDefinition,...]|None=None)->None: self._definitions={i.id:i for i in definitions or DEFAULT_WORKFLOWS}; self.validate() + def get(self,workflow_id:str)->WorkflowDefinition: + try:return self._definitions[workflow_id] + except KeyError as exc: raise WorkflowError(f"Unknown workflow: {workflow_id}") from exc + def all(self)->tuple[WorkflowDefinition,...]: return tuple(self._definitions.values()) + def validate(self)->None: + if not self._definitions: raise WorkflowError("Workflow registry must not be empty") + for d in self._definitions.values(): + if not d.stages or d.stages[0] is not WorkflowStage.INPUT: raise WorkflowError(f"Workflow {d.id} must start with INPUT") + if WorkflowStage.QUALITY not in d.stages: raise WorkflowError(f"Workflow {d.id} requires a QUALITY gate") + if len(set(d.stages))!=len(d.stages): raise WorkflowError(f"Workflow {d.id} contains duplicate stages") +class WorkflowEngine: + def __init__(self,registry:WorkflowRegistry|None=None)->None:self.registry=registry or WorkflowRegistry() + def run(self,workflow_id:str,payload:Mapping[str,Any],executor:Executor)->WorkflowContext: + d=self.registry.get(workflow_id); context=WorkflowContext(d.id,dict(payload)) + for stage in d.stages: + context.stage=stage; context=executor(stage,context) + if not isinstance(context,WorkflowContext): raise WorkflowError(f"Executor returned invalid context at stage {stage}") + context.record_evidence("workflow.completed",d.id); return context +def _definition(factory:FactoryId,name:str,capabilities:tuple[str,...],outputs:tuple[str,...],description:str)->WorkflowDefinition: + return WorkflowDefinition(factory.value,name,(WorkflowStage.INPUT,WorkflowStage.ANALYZE,WorkflowStage.PLAN,WorkflowStage.PRODUCE,WorkflowStage.QUALITY,WorkflowStage.INTEGRATE,WorkflowStage.PUBLISH,WorkflowStage.MONITOR,WorkflowStage.OPTIMIZE),capabilities,outputs,description) +DEFAULT_WORKFLOWS=( +_definition(FactoryId.TEXT,"Text / Content Factory",("writing","translation","seo"),("content","localized-content"),"Text and content production."), +_definition(FactoryId.SOFTWARE,"Software Factory",("specification","architecture","code","tests","deployment"),("source","tests","documentation","release"),"Software delivery from idea to deployment."), +_definition(FactoryId.GAME,"Game Factory",("game-design","world","lore","characters","quests","gameplay","assets","ai-npc","testing","liveops"),("game-bible","game-content","build","liveops-plan"),"End-to-end game production."), +_definition(FactoryId.MARKETING,"Marketing Factory",("campaigns","ads","landing-pages","experiments","analytics"),("campaign","creative-plan","report"),"Campaign planning and optimization."), +_definition(FactoryId.BUSINESS,"Business Factory",("business-model","market-analysis","financial-model","pricing","kpis"),("business-plan","financial-model","kpi-plan"),"Business model production."), +_definition(FactoryId.DOCUMENT,"Document Factory",("contracts","offers","reports","sops","manuals"),("documents","document-set"),"Controlled business document production."), +_definition(FactoryId.RESEARCH,"Research Factory",("research","source-analysis","monitoring","synthesis"),("research-report","knowledge-update"),"Evidence-oriented research workflows."), +_definition(FactoryId.ECOMMERCE,"E-Commerce Factory",("catalog","product-analysis","pricing","sales-analysis"),("catalog","product-content","sales-report"),"E-commerce content and operations."), +_definition(FactoryId.CUSTOMER_SERVICE,"Customer-Service Factory",("support","faq","triage","crm","escalation"),("resolution","faq-update","support-report"),"Customer support automation."), +_definition(FactoryId.AUTOMATION,"Automation Factory",("triggers","agents","apis","data","notifications"),("automation","execution-log"),"Event-driven multi-step automation."), +_definition(FactoryId.KNOWLEDGE,"Knowledge Factory",("ingestion","rag","semantic-search","knowledge-graph","memory"),("knowledge-base","index","graph"),"Document-to-knowledge transformation."), +_definition(FactoryId.AGENT,"Agent Factory",("identity","tools","memory","permissions","workflows","agent-messaging"),("agent-definition","policy","workflow"),"Controlled AI-agent creation."), +_definition(FactoryId.FRANCHISE,"Franchise Factory",("business-model","brand","product","content","software","marketing","sales","automation","replication"),("franchise-package","operating-model","replication-plan"),"Replicate a validated business system as a franchise package."), +_definition(FactoryId.STARTUP,"Startup Factory",("validation","mvp","branding","product","launch","kpis"),("startup-package","mvp-plan","launch-plan"),"Startup formation from idea to launch."), +_definition(FactoryId.EDUCATION,"Education Factory",("curriculum","learning-material","exercises","assessment","tutoring"),("course","learning-platform-plan","assessment"),"Education product production."), +_definition(FactoryId.BOOK,"Book Factory",("research","outline","writing","editing","layout","translation","publishing"),("manuscript","book-package","publication-plan"),"Book production and publication."), +_definition(FactoryId.VIRTUAL_WORLD,"Virtual World Factory",("world","geography","cities","buildings","npcs","economy","factions","lore","simulation"),("world-bible","world-data","simulation"),"Persistent virtual-world production."),) +GAME_SUBSYSTEMS:Mapping[str,tuple[str,...]]={"concept":("genre","target","platforms","usp","core-loop","modes","monetization","technical-requirements"),"world":("continents","regions","biomes","cities","dungeons","buildings","climate","day-night","weather","portals"),"lore":("origin","peoples","factions","wars","timeline","secrets","canon","artifacts"),"character":("player","npc","classes","attributes","skills","progression","relationships"),"creature":("anatomy","abilities","weaknesses","attacks","movement","loot","variants","boss-mechanics"),"combat":("melee","ranged","magic","combos","dodge","parry","status","boss-phases","pvp-balance"),"quest":("main","side","faction","events","puzzles","boss","hidden","dynamic"),"level":("terrain","rooms","paths","encounters","loot","checkpoints","puzzles","secrets","scaling"),"item":("weapons","armor","accessories","consumables","resources","relics","artifacts","skins","crafting"),"weapon":("concept","design","3d","animation","vfx","sound","gameplay"),"animation":("idle","walk","run","jump","attack","combo","hit","death","emotes","interactions"),"ai-npc":("identity","memory","personality","goals","knowledge","behavior","routine","relationships"),"audio":("sfx","voice","ambient","music","dynamic-music","spatial-audio"),"vfx":("fire","water","explosions","magic","energy","portals","weather","abilities","boss-effects"),"economy":("loot","resources","crafting","pricing","demand","inflation","progression","rewards"),"multiplayer":("matchmaking","lobby","party","guilds","pvp","pve","raids","leaderboards","seasons","server"),"testing":("bugs","exploits","levels","combat","quests","economy","performance","network","ui","progression","ai-playtests"),"liveops":("telemetry","retention","funnel","balance","bugs","seasons","events","content")} From 83ff89af5d5bbe3ce304f86eb51355e809c5e2f4 Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:05:57 +0200 Subject: [PATCH 07/13] feat(franchise-factory): migrate spec loader --- franchise_factory/gff/spec_loader.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 franchise_factory/gff/spec_loader.py diff --git a/franchise_factory/gff/spec_loader.py b/franchise_factory/gff/spec_loader.py new file mode 100644 index 0000000..b9d3879 --- /dev/null +++ b/franchise_factory/gff/spec_loader.py @@ -0,0 +1,28 @@ +"""Laedt und validiert die kanonischen .atc-Factory-Specs (AD-20..AD-43).""" +from __future__ import annotations +import re +from dataclasses import dataclass, field +from pathlib import Path +AD_RE=re.compile(r"^//\s*AD-(\d+)\s*(?:[—\-]+\s*)?(.+)$",re.MULTILINE); STRUCT_RE=re.compile(r"struct\s+(\w+)"); ENUM_RE=re.compile(r"enum\s+(\w+)"); FN_RE=re.compile(r"pub\s+fn\s+(\w+)"); COPYRIGHT_RE=re.compile(r"Copyright \(c\) 2026"); FORBIDDEN_RE=re.compile(r'import\s+"?[^"\n]*chronicles',re.IGNORECASE) +@dataclass(frozen=True) +class FactorySpec: + ad_id:int; title:str; file:str; structs:tuple[str,...]=(); enums:tuple[str,...]=(); functions:tuple[str,...]=(); raw:str=field(default="",repr=False,compare=False) + @property + def has_implementation_surface(self)->bool:return bool(self.structs) and bool(self.functions) +class SpecValidationError(ValueError):pass +def load_spec(path:Path)->FactorySpec: + raw=path.read_text(encoding="utf-8"); m=AD_RE.search(raw) + if not m: raise SpecValidationError(f"{path.name}: kein '// AD-xx — Titel'-Header") + ad_id=int(m.group(1)) + if not COPYRIGHT_RE.search(raw): raise SpecValidationError(f"{path.name}: Copyright-Header fehlt") + if FORBIDDEN_RE.search(raw): raise SpecValidationError(f"{path.name}: verbotene Abhaengigkeit 'chronicles' (Plattform-Trennung)") + ad_in_name=re.search(r"_ad(\d+)\.atc$",path.name) + if ad_in_name and int(ad_in_name.group(1))!=ad_id: raise SpecValidationError(f"{path.name}: AD-ID im Dateinamen ({ad_in_name.group(1)}) != Header ({ad_id})") + return FactorySpec(ad_id,m.group(2).strip(),path.name,tuple(STRUCT_RE.findall(raw)),tuple(ENUM_RE.findall(raw)),tuple(FN_RE.findall(raw)),raw) +def load_specs(spec_dir:Path)->dict[int,FactorySpec]: + specs={} + for p in sorted(spec_dir.glob("*_ad*.atc")): + s=load_spec(p) + if s.ad_id in specs: raise SpecValidationError(f"AD-{s.ad_id:02d} doppelt: {specs[s.ad_id].file} vs {s.file}") + specs[s.ad_id]=s + return specs From 4d3e3b6178aa6d2509a94ce4a19dd7683cdb7dbd Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:06:09 +0200 Subject: [PATCH 08/13] feat(franchise-factory): migrate lifecycle manager --- franchise_factory/gff/lifecycle.py | 50 ++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 franchise_factory/gff/lifecycle.py diff --git a/franchise_factory/gff/lifecycle.py b/franchise_factory/gff/lifecycle.py new file mode 100644 index 0000000..64c8285 --- /dev/null +++ b/franchise_factory/gff/lifecycle.py @@ -0,0 +1,50 @@ +"""Lifecycle Manager (AD-43).""" +from __future__ import annotations +import hashlib,time +from dataclasses import dataclass,field +from enum import Enum +class LPhase(Enum): + IDEA="Idea"; CONCEPT="Concept"; PROTOTYPE="Prototype"; PRE_PROD="PreProd"; PRODUCTION="Production"; ALPHA="Alpha"; BETA="Beta"; RELEASE="Release"; LIVE_OPS="LiveOps"; EXPANSION="Expansion"; SUCCESSOR="Successor"; ARCHIVED="Archived" +_PHASE_ORDER=[p for p in LPhase] +class MStatus(Enum): NOT_STARTED="NotStarted"; IN_PROGRESS="InProgress"; ACHIEVED="Achieved" +@dataclass +class KPI: + dau:int=0; mau:int=0; revenue:float=0.0; retention:float=0.0; crash_free:float=100.0; rating:float=0.0; sentiment:float=0.5 +@dataclass +class Milestone: + id:str; fid:str; name:str; phase:LPhase; target:int; achieved:int=0; status:MStatus=MStatus.NOT_STARTED; criteria:list[str]=field(default_factory=list); done:list[str]=field(default_factory=list) +@dataclass +class LFranchise: + id:str; name:str; phase:LPhase; history:list[dict]=field(default_factory=list); start:float=0.0; target:float=0.0; budget:float=0.0; spent:float=0.0; team:list[str]=field(default_factory=list); risk:int=5; prob:float=0.5; milestones:list[str]=field(default_factory=list); kpi:KPI=field(default_factory=KPI) +@dataclass +class PhaseTemplate: + phase:LPhase; name:str; desc:str; duration_days:int; deliverables:list[str]; criteria:list[str] +def _init_templates(): + spec=[(LPhase.IDEA,"Idea","Concept",14,["Vision"],["Approved"]),(LPhase.CONCEPT,"Concept","Design",30,["GDD"],["GDD OK"]),(LPhase.PROTOTYPE,"Prototype","Playable",60,["Slice"],["Playable"]),(LPhase.PRE_PROD,"PreProd","Planning",90,["Plan"],["Plan OK"]),(LPhase.PRODUCTION,"Production","Content",365,["Levels"],["Complete"]),(LPhase.ALPHA,"Alpha","Features",60,["Features"],["Alpha"]),(LPhase.BETA,"Beta","Polish",60,["Bugs"],["Beta"]),(LPhase.RELEASE,"Release","Launch",30,["Gold"],["Launched"]),(LPhase.LIVE_OPS,"LiveOps","Ops",0,["Seasons"],["Active"]),(LPhase.EXPANSION,"Expansion","DLC",180,["DLC"],["DLC OK"]),(LPhase.SUCCESSOR,"Successor","Next",365,["Plan"],["New"]),(LPhase.ARCHIVED,"Archived","End",0,[],["Closed"])] + return {p:PhaseTemplate(p,n,d,dur,de,cr) for p,n,d,dur,de,cr in spec} +class LifecycleManager: + def __init__(self): self.franchises={}; self.templates=_init_templates(); self.transitions=[]; self.milestones={}; self._now=time.time() + def register(self,name,budget=0.0,target=0.0,*,now=None): + if not name: raise ValueError("register: name leer") + ts=self._now if now is None else now; fid=hashlib.sha256(f"{name}|{ts}".encode()).hexdigest()[:16] + self.franchises[fid]=LFranchise(fid,name,LPhase.IDEA,[{"phase":LPhase.IDEA,"entered":ts,"exited":0.0,"notes":"Created","success":False}],ts,target,budget); return fid + @staticmethod + def _validate_transition(old,new): + a,b=_PHASE_ORDER.index(old),_PHASE_ORDER.index(new); return b==a+1 or new==LPhase.ARCHIVED + def transition(self,fid,new_phase,by,notes="",*,now=None): + fr=self.franchises.get(fid) + if fr is None: raise KeyError(f"Franchise {fid} nicht gefunden") + if not self._validate_transition(fr.phase,new_phase): raise ValueError(f"Ungueltiger Uebergang {fr.phase.value} -> {new_phase.value}") + ts=self._now if now is None else now; old=fr.phase; fr.history[-1].update(exited=ts,success=True); fr.phase=new_phase; fr.history.append({"phase":new_phase,"entered":ts,"exited":0.0,"notes":notes,"success":False}); self.transitions.append({"id":hashlib.sha256(f"{fid}|{ts}".encode()).hexdigest()[:16],"fid":fid,"from":old,"to":new_phase,"timestamp":ts,"by":by,"notes":notes}); return True + def add_milestone(self,fid,name,phase,target,criteria): + fr=self.franchises.get(fid) + if fr is None: raise KeyError(f"Franchise {fid} nicht gefunden") + mid=hashlib.sha256(f"{name}|{self._now}".encode()).hexdigest()[:16]; self.milestones[mid]=Milestone(mid,fid,name,phase,target,criteria=list(criteria)); fr.milestones.append(mid); return mid + def achieve_milestone(self,mid,achieved,done): + m=self.milestones.get(mid) + if m is None: raise KeyError(f"Milestone {mid} nicht gefunden") + m.achieved=achieved; m.done=list(done); m.status=MStatus.ACHIEVED if achieved>=m.target else MStatus.IN_PROGRESS; return m.status==MStatus.ACHIEVED + def health(self,fid): + fr=self.franchises.get(fid) + if fr is None: raise KeyError(f"Franchise {fid} nicht gefunden") + return {"phase":fr.phase.value,"risk":fr.risk,"prob":fr.prob,"budget_used_ratio":round(fr.spent/fr.budget,4) if fr.budget else 0.0,"kpi_dau":fr.kpi.dau,"kpi_crash_free":fr.kpi.crash_free} From 3b014c51b5ffed4d57e100bc0d21aa6c220082af Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:06:32 +0200 Subject: [PATCH 09/13] feat(franchise-factory): add integrated Python package metadata --- franchise_factory/pyproject.toml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 franchise_factory/pyproject.toml diff --git a/franchise_factory/pyproject.toml b/franchise_factory/pyproject.toml new file mode 100644 index 0000000..87e5161 --- /dev/null +++ b/franchise_factory/pyproject.toml @@ -0,0 +1,18 @@ +[build-system] +requires = ["setuptools>=68"] +build-backend = "setuptools.build_meta" + +[project] +name = "atc-genesis-franchise-factory" +version = "0.1.0" +description = "Genesis Franchise Factory integrated into Genesis Engine" +requires-python = ">=3.11" + +[project.optional-dependencies] +dev = ["pytest>=8", "ruff>=0.6"] + +[tool.pytest.ini_options] +testpaths = ["tests"] + +[tool.setuptools] +packages = ["gff"] From 3dbd5bff0e7e71a69aac9f0dcf006c7fb351f3ee Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:06:40 +0200 Subject: [PATCH 10/13] docs(franchise-factory): document integrated engine architecture --- franchise_factory/README.md | 49 +++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 franchise_factory/README.md diff --git a/franchise_factory/README.md b/franchise_factory/README.md new file mode 100644 index 0000000..d562e4e --- /dev/null +++ b/franchise_factory/README.md @@ -0,0 +1,49 @@ +# Genesis Franchise Factory + +The Franchise Factory is now an integrated production subsystem of `genesis-engine`. + +## Boundary + +```text +Franchise Factory + ├─ 17 AI production workflows + ├─ Game Factory dependency graph + ├─ Artifact + provenance contracts + ├─ Franchise core pipeline + ├─ DAO model + └─ Lifecycle Manager + │ + ▼ +Genesis Engine Runtime / Build / Editor / SDK + │ + ▼ +Games and franchises +``` + +`genesis-chronicles` remains an independent consumer/flagship title and is not a dependency of this subsystem. + +## Components + +- `gff/core.py` — AD-20 franchise registry and pipeline orchestration +- `gff/dao.py` — ATC-9900 franchise DAO model +- `gff/lifecycle.py` — AD-43 lifecycle state machine +- `gff/spec_loader.py` — canonical `.atc` descriptor loader +- `gff/workflows.py` — 17 provider-neutral AI factory workflows +- `gff/artifacts.py` — typed artifact/provenance/evidence contracts +- `gff/game_factory.py` — deterministic Game Factory dependency graph + +## Game Factory + +The Game Factory models Concept, World, Lore, Character, Creature, Combat, Quest, Level, Item, Weapon, Animation, AI NPC, Audio, VFX, Economy, Multiplayer, Build, Testing and LiveOps as typed production stages. + +The graph fails closed on missing producers and dependency cycles and exposes a deterministic topological order. + +## AI boundary + +The workflow engine does not call an AI provider directly. Model providers, credentials and external side effects are supplied through injected executors. This preserves deterministic orchestration and keeps provider concerns outside the core. + +## Engine integration + +The subsystem is located under `franchise_factory/` rather than being made a Rust workspace member. This preserves the existing Python reference implementation while making the Franchise Factory part of the Genesis Engine repository and CI/documentation surface. + +Production adapters to engine runtime systems, GCL/ATC-VM and external providers remain explicit integration boundaries and must be backed by implementation evidence before being marked production-ready. From d19afc38021110fc0b12b2fe9c77f5ea582108e8 Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:06:47 +0200 Subject: [PATCH 11/13] test(franchise-factory): add integrated subsystem regression tests --- franchise_factory/tests/test_integration.py | 47 +++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 franchise_factory/tests/test_integration.py diff --git a/franchise_factory/tests/test_integration.py b/franchise_factory/tests/test_integration.py new file mode 100644 index 0000000..4c23a2d --- /dev/null +++ b/franchise_factory/tests/test_integration.py @@ -0,0 +1,47 @@ +from gff.artifacts import ArtifactKind, ArtifactRef +from gff.game_factory import GAME_FACTORY_GRAPH, dependency_refs, topological_order +from gff.workflows import FactoryId, WorkflowContext, WorkflowEngine, WorkflowStage +from gff.core import FranchiseBlueprint, GFFCore +from gff.lifecycle import LPhase, LifecycleManager + + +def test_workflow_catalog_and_execution(): + seen = [] + def executor(stage, context): + seen.append(stage) + return context + result = WorkflowEngine().run(FactoryId.GAME.value, {"name": "Example"}, executor) + assert seen[0] is WorkflowStage.INPUT + assert WorkflowStage.QUALITY in seen + assert result.evidence[-1]["kind"] == "workflow.completed" + + +def test_game_factory_graph_is_acyclic_and_complete(): + order = topological_order() + assert len(order) == len(GAME_FACTORY_GRAPH) + assert order.index("item") < order.index("economy") < order.index("multiplayer") < order.index("build") < order.index("testing") < order.index("liveops") + + +def test_dependency_resolution_fails_closed(): + node = next(n for n in GAME_FACTORY_GRAPH if n.id == "economy") + refs = (ArtifactRef("game", ArtifactKind.GAME_BIBLE, producer="concept"), ArtifactRef("items", ArtifactKind.ITEM, producer="item")) + assert [r.kind for r in dependency_refs(node, refs)] == [ArtifactKind.GAME_BIBLE, ArtifactKind.ITEM] + + +def test_core_franchise_pipeline(): + core = GFFCore() + fid = core.create_franchise(FranchiseBlueprint(name="Example", genre="RPG"), now=1.0) + assert core.run_pipeline(fid) + assert core.franchises[fid].progress == 1.0 + + +def test_lifecycle_is_forward_only(): + manager = LifecycleManager() + fid = manager.register("Example", now=1.0) + assert manager.transition(fid, LPhase.CONCEPT, "test", now=2.0) + try: + manager.transition(fid, LPhase.IDEA, "test", now=3.0) + except ValueError: + pass + else: + raise AssertionError("Lifecycle rollback must fail closed") From ee00e1fd8fdeb26523e2bdd6ba07dfa20e12ea7f Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:06:52 +0200 Subject: [PATCH 12/13] ci(franchise-factory): add integrated Python quality gates --- .github/workflows/franchise-factory.yml | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/franchise-factory.yml diff --git a/.github/workflows/franchise-factory.yml b/.github/workflows/franchise-factory.yml new file mode 100644 index 0000000..1385091 --- /dev/null +++ b/.github/workflows/franchise-factory.yml @@ -0,0 +1,30 @@ +name: Franchise Factory Quality Gates + +on: + push: + branches: [main] + pull_request: + paths: + - 'franchise_factory/**' + - '.github/workflows/franchise-factory.yml' + +permissions: + contents: read + +jobs: + franchise-factory: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-python@v6 + with: + python-version: '3.11' + - name: Install Franchise Factory + working-directory: franchise_factory + run: python -m pip install -e '.[dev]' + - name: Ruff + working-directory: franchise_factory + run: ruff check gff tests + - name: Pytest + working-directory: franchise_factory + run: pytest -q From e786b012e592d38d0c6550fcc6f24b7173b89232 Mon Sep 17 00:00:00 2001 From: ShivaCoreDev Date: Thu, 17 Sep 2026 17:07:06 +0200 Subject: [PATCH 13/13] docs(franchise-factory): document migration into Genesis Engine --- README.md | 216 ++++++++++++++++-------------------------------------- 1 file changed, 62 insertions(+), 154 deletions(-) diff --git a/README.md b/README.md index 569004f..66d2635 100644 --- a/README.md +++ b/README.md @@ -12,16 +12,14 @@ ownership: organization: A-TownChain-Okosystems technology: primary_language: Rust -governance: - security_class: S1 - criticality: low + secondary_language: Python --> # ATC Genesis Engine [![ATC-COMPLIANCE](https://img.shields.io/badge/ATC-COMPLIANCE-v1.0-green)](./AGENTS.md) -> General-purpose, modulare Game-Engine für ECS, Weltensimulation, Rendering, Physik, Audio, Animation, Networking, AI und Editor-Workflows. +> General-purpose, modulare Game-Engine für ECS, Weltensimulation, Rendering, Physik, Audio, Animation, Networking, AI, Editor und Franchise-Production-Workflows. **Project:** `genesis-engine` **Organization:** `A-TownChain-Okosystems` @@ -31,35 +29,41 @@ governance: ## Overview -Genesis Engine ist die **general-purpose Game-Development-Plattform** des A-TownChain-Ökosystems. Die Engine stellt wiederverwendbare Runtime-, Simulations-, Tooling- und SDK-Funktionen bereit. `genesis-chronicles` ist ein unabhängiger Consumer/Flagship-Titel und keine technische Voraussetzung für die Engine. - -Die kanonische Cargo-Workspace-Struktur besteht aus den folgenden Modulen: - -| Modul | Verantwortung | -|---|---| -| `atc-genesis-animation` | Animation und Animationslaufzeit | -| `atc-genesis-assets` | Asset-Verträge, Ressourcen und Content-Pipeline-Basis | -| `atc-genesis-audio` | Audio-Runtime und Audio-Abstraktionen | -| `atc-genesis-ecs` | Entity Component System und World/ECS-Bridge | -| `atc-genesis-physics` | Physik-Abstraktion und Simulation | -| `atc-genesis-platform` | Gemeinsame Primitive und Backend-Interfaces | -| `atc-genesis-renderer` | Rendering-Abstraktion | -| `atc-genesis-ui` | UI-Abstraktionen | -| `atc-genesis-sdk` | Öffentliche Engine-/SDK-Schnittstellen | -| `atc-genesis-ai` | AI-Integration | -| `atc-genesis-network` | Networking und Replikation | -| `atc-genesis-build` | Build- und Packaging-Funktionen | -| `atc-genesis-tools` | Entwickler- und Engine-Tools | -| `atc-genesis-cli` | Kommandozeilenwerkzeuge | -| `atc-genesis-editor` | Editor-Funktionen | -| `atc-genesis-input` | Input-Abstraktionen | -| `atc-genesis-world` | Welt- und Chunk-Simulation | -| `atc-genesis-gameplay` | Generische Gameplay-Systeme | -| `atc-genesis-runtime` | Runtime-Orchestrierung und Subsystem-Lifecycle | - -Der **kanonische Runtime-Kern** ist damit `atc-genesis-runtime`. Ein Cargo-Paket `atc-genesis-engine` ist aktuell **kein Workspace-Mitglied**. Historische Dateien unter `modules/atc-genesis-engine/` dürfen nicht mit dem aktuellen Rust-Workspace verwechselt werden und müssen bei der weiteren Migration separat behandelt werden. - -Die Engine befindet sich im Rebuild und ist **nicht als Production-Ready oder finaler Releasezustand** zu verstehen. +Genesis Engine ist die **general-purpose Game-Development-Plattform** des A-TownChain-Ökosystems. Die Engine stellt wiederverwendbare Runtime-, Simulations-, Tooling-, SDK- und Produktionsfunktionen bereit. `genesis-chronicles` ist ein unabhängiger Consumer/Flagship-Titel und keine technische Voraussetzung für die Engine. + +Die kanonische Cargo-Workspace-Struktur umfasst Runtime-, Simulation-, Rendering-, AI-, Networking-, Editor-, Build- und SDK-Module. Zusätzlich ist die **Genesis Franchise Factory** als integrierter Produktionssubsystem-Bereich unter `franchise_factory/` Bestandteil dieses Repositories. + +## Genesis Franchise Factory + +Die Franchise Factory ist jetzt im Genesis-Engine-Repository verankert und umfasst die vollständige Orchestrierungsbasis: + +- 17 AI-Produktions-Workflows +- Franchise Core / AD-20 Pipeline +- DAO-Modell / ATC-9900 +- Lifecycle Manager / AD-43 +- Typed Artifact + Provenance/Evidence Contracts +- Game Factory Dependency Graph mit Build, QA und LiveOps +- Python-Referenzimplementierung und integrierte Regressionstests +- eigene Python-Quality-Gates in GitHub Actions + +```text +franchise_factory/ +├── gff/ +│ ├── core.py +│ ├── dao.py +│ ├── lifecycle.py +│ ├── spec_loader.py +│ ├── workflows.py +│ ├── artifacts.py +│ └── game_factory.py +├── tests/ +├── specs/ +└── docs/ +``` + +Die Factory sitzt innerhalb der Engine-Plattform, ohne `genesis-chronicles` zur technischen Abhängigkeit zu machen. Provider, externe Side Effects und Chain-/VM-Anbindungen bleiben explizite Integrationsgrenzen und werden nicht als implementiert ausgegeben, solange keine Evidence vorliegt. + +Weitere Details: [`franchise_factory/README.md`](franchise_factory/README.md). ## Purpose @@ -74,6 +78,7 @@ Genesis Engine ist für die generische Laufzeit- und Simulationsinfrastruktur de - AI- und Networking-Integration - Editor- und Entwicklerwerkzeuge - SDK- und Build-/Packaging-Infrastruktur +- Franchise- und Game-Production-Orchestrierung über die integrierte Franchise Factory Spielspezifische Logik gehört in das jeweilige Spiel-Repository. Generische Features werden nur über den vorgesehenen Feature-Promotion-Prozess in die Engine übernommen. @@ -93,31 +98,8 @@ AI / Network / Renderer / UI Runtime ↓ Editor / Tools / CLI / Build / SDK -``` - -Die tatsächlichen Cargo-Abhängigkeiten sind maßgeblich; diese Darstellung ist ein Architekturmodell und ersetzt keine `Cargo.toml`-Definition. - -### Runtime data flow - -```text -Input - ↓ -Fixed Simulation Tick - ├── ECS - ├── Gameplay - ├── Physics - ├── Animation - ├── AI - └── World / Streaming - ↓ -Authoritative State - ├── Network replication - ├── Audio - └── Render preparation - ↓ - Renderer - ↓ - Present + ↓ + Franchise Factory / Production Orchestration ``` ### Ecosystem Boundary @@ -131,31 +113,23 @@ ATCLang / ATC-VM / A-TownChain │ ▼ Genesis Engine - │ - ▼ - Genesis Chronicles / Games + ┌─────┴─────┐ + │ │ + Franchise Runtime/Editor + Factory │ + │ ▼ + └──────► Games / Franchises ``` Die Engine ist keine Blockchain, kein Kernel und kein Ersatz für ATC-VM oder ShivaCore. Chain-seitige Zustandsübergänge und Contracts bleiben an der vorgesehenen Chain-/VM-Grenze. ## Determinism -Deterministische Simulation ist ein explizites Engine-Ziel. Für deterministische Pfade müssen insbesondere folgende Bereiche kontrolliert werden: - -- ECS-Iteration und Systemreihenfolge -- RNG und Seeds -- Gameplay-State -- Physik -- Welt-/Chunk-Streaming -- Netzwerk-Ticks -- Serialisierung -- Replay-/State-Verification - -Ungeordnete Datenstrukturen dürfen auf einem deterministischen Simulationspfad nicht unkontrolliert die Ausführungsreihenfolge bestimmen. +Deterministische Simulation ist ein explizites Engine-Ziel. Für deterministische Pfade müssen ECS-Iteration, RNG/Seeds, Gameplay-State, Physik, Streaming, Netzwerk-Ticks, Serialisierung und Replay/State-Verification kontrolliert werden. ## AI Boundary -Externe oder asynchrone AI darf den deterministischen Simulationszustand nicht direkt verändern. Der Zielpfad ist: +Externe oder asynchrone AI darf den deterministischen Simulationszustand nicht direkt verändern: ```text AI Inference @@ -167,10 +141,12 @@ Deterministic Simulation State Change ``` +Die Franchise Factory folgt demselben Prinzip: Workflows sind provider-neutral; AI-Provider und externe Aktionen werden über injizierte Executor-Grenzen angeschlossen. + ## Requirements - Rust >= 1.75 / Cargo -- Python >= 3.11 für vorhandenes Tooling und historische Sync-Skripte +- Python >= 3.11 für Franchise-Factory-Tooling und vorhandenes Tooling - Git >= 2.30 ## Installation @@ -179,6 +155,9 @@ State Change git clone https://github.com/A-TownChain-Okosystems/genesis-engine.git cd genesis-engine cargo build --workspace +cd franchise_factory +python -m pip install -e '.[dev]' +pytest -q ``` ## Testing @@ -189,108 +168,37 @@ cargo check --workspace --all-targets cargo test --workspace --all-targets cargo clippy --workspace --all-targets -- -D warnings cargo doc --workspace --no-deps -``` -Security-/Dependency-Prüfungen und Engine-spezifische Gates laufen zusätzlich über GitHub Actions. +cd franchise_factory +ruff check gff tests +pytest -q +``` Testergebnisse sind Evidence. Ein erfolgreicher Testlauf bedeutet nicht automatisch `AUDITED` oder `PRODUCTION_READY`. -## Development - -Entwicklung erfolgt nach den geltenden A-TownChain-Governance- und Repository-Standards. Commits müssen dem Conventional-Commit-Modell entsprechen. - -Vor größeren Änderungen sind mindestens `STATUS.md`, `AGENT_MANIFEST.md`, `ARCHITECTURE.md`, `ROADMAP.md` und die relevanten Governance-Dokumente zu prüfen. - -## Security - -Security Issues dürfen nicht öffentlich über GitHub Issues gemeldet werden. Sicherheitslücken sind über den offiziellen Security-Reporting-Prozess in `SECURITY.md` zu melden. - -**Security class:** S1 -**Criticality:** low - -## Audit - -Der laufende Engineering-Audit wird in folgenden Dateien dokumentiert: - -- `docs/ENGINEERING_AUDIT.md` — Audit-Baseline und Evidenzstatus -- `docs/ENGINEERING_AUDIT_FINDINGS.md` — Finding Registry und Remediation-Status - -Definition of Done für Findings: - -```text -Finding - → Root Cause - → Fix - → Regression Test - → CI Verification - → Audit Evidence - → CLOSED -``` - ## Documentation - `ARCHITECTURE.md` — technische Architektur - `STATUS.md` — aktueller Projektstatus - `ROADMAP.md` — Entwicklungs-Roadmap +- `franchise_factory/README.md` — integrierte Franchise Factory +- `franchise_factory/gff/` — Factory Runtime/Orchestration - `docs/ENGINEERING_AUDIT.md` — Audit-Baseline - `docs/ENGINEERING_AUDIT_FINDINGS.md` — Findings -- `docs/specs/GEN-PROD-001-PRODUCT-STRATEGY.md` — Produktstrategie -- `docs/REPOSITORY_STANDARD.md` — Repository-Standard -- `a-townchain-os-docs` — zentrale Ökosystem-Dokumentation ## Governance -Das Repository folgt dem A-TownChain-Governance-Modell. Architektur- und Governance-Entscheidungen müssen über die vorgesehenen Entscheidungs- und Review-Prozesse erfolgen. - -Canonical Standard-IDs werden ausschließlich über die Standards Registry und den dafür definierten Governance-Prozess vergeben. Die aktuelle Taxonomie verwendet Family-scoped IDs der Form `ATC-STD-Fxx-yyy`; bestehende Legacy-IDs bleiben historisch erhalten und werden nicht stillschweigend umnummeriert. - -## Standards & Compliance - -| Standard | Version | Verwendung | -|---|---:|---| -| ATC-STD-000 | 1.3.0 | Governance Root | -| ATC-STD-README-001 | 1.0.0 | README-Struktur und Metadaten | -| ATC-STD-MD-001 | 1.0.0 | Markdown-Konformität | -| ATC-STD-201 | 1.0.1 | Repository Governance | -| ATC-STD-202 | 1.2.0 | Repository/Entwicklungsanforderungen | -| ATC-STD-203 | 1.0.1 | Security und Release Gates | - -Die Tabelle dokumentiert relevante Standards; sie ist keine pauschale Behauptung, dass dieses Entwicklungs-Repository bereits `PRODUCTION_READY` ist. - -## Roadmap - -Siehe: - -- `ROADMAP.md` -- `STATUS.md` -- zentrale Roadmap in `a-townchain-os-docs` -- GitHub Issues & Projects - -## Contributing - -Beiträge erfolgen über den definierten ATC-Governance-Prozess. Vor einem Merge müssen die für die Änderung relevanten Tests und Validatoren erfolgreich ausgeführt werden. +Das Repository folgt dem A-TownChain-Governance-Modell und den geltenden ATC-Standards. Änderungen an Factory-, Engine-, Chain- oder VM-Grenzen müssen nachvollziehbar dokumentiert und durch Tests/Evidence belegt werden. ## License Apache-2.0 — A-TownChain-Okosystems. Details siehe [`LICENSE`](LICENSE). -## Maintainers - -**Organization:** A-TownChain-Okosystems -**Maintainers:** ShivaCoreDev, aurora-superagent - -## Repository Metadata - -Maschinenlesbar: siehe HTML-Metadaten-Block im Header gemäß ATC-STD-README-001 §14. -**Registry-ID:** `ATC-REPO-GAME-001` - ## AI Agent Instructions -Für KI-Agenten: - 1. Lies `STATUS.md`, `AGENT_MANIFEST.md`, `ARCHITECTURE.md` und `ROADMAP.md` vor größeren Änderungen. 2. Beachte die geltenden ATC-Standards und Repository-Governance. 3. Verwende Conventional Commits. -4. Führe nach Änderungen mindestens `cargo fmt --all -- --check`, `cargo check --workspace --all-targets`, `cargo test --workspace --all-targets` und `cargo clippy --workspace --all-targets -- -D warnings` aus. +4. Führe Engine- und Franchise-Factory-Tests aus. 5. Trenne deklarierte Zustände, Testergebnisse und Governance-Evidence strikt voneinander. 6. Verändere keine Chain-/VM-Grenzen, um Engine-Funktionalität zu implementieren.