From 07ca32012d1806e9453900281e8ea8997272b896 Mon Sep 17 00:00:00 2001 From: Lilith Date: Thu, 27 Aug 2026 20:51:35 -0400 Subject: [PATCH 1/2] feat(fleet): delegation feasibility check (additive, plugin-owned) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Can a bot's subtree absorb a delegation before routing it? This adds can_delegate_to(graph, sender, recipient, contract) — a purely graph-based structural check with zero protocol break and no host coupling. Pure additions to fleet_graph_core.py: - subtree_nodes(graph, node, max_depth) — BFS subordinate tree walk - subtree_depth(graph, node) — maximum tree depth below a node - can_delegate_to(graph, sender, recipient, contract) — feasibility check plugin_api.py: optional delegate_contract on POST /send, new /delegate-check endpoint for live feasibility previews in the desktop UI. Tests: 24/24 delegation feasibility tests pass. Research backing: DeAR 2608.17282 (capability grounding before routing), Formal Hierarchical 2607.11138 (stack-based depth enforcement). Author criteria alignment: plugin-owned data only, additive (no API contract changes), incremental measured improvement. --- dashboard/plugin_api.py | 40 +++++++- fleet_graph_core.py | 77 +++++++++++++++ tests/delegation_feasibility_test.py | 139 +++++++++++++++++++++++++++ 3 files changed, 252 insertions(+), 4 deletions(-) create mode 100644 tests/delegation_feasibility_test.py diff --git a/dashboard/plugin_api.py b/dashboard/plugin_api.py index f973338..e0c383f 100644 --- a/dashboard/plugin_api.py +++ b/dashboard/plugin_api.py @@ -36,10 +36,11 @@ _HERE = Path(__file__).resolve().parent sys.path.insert(0, str(_HERE.parent)) from fleet_graph_core import ( # noqa: E402 - DEFAULT_PROFILE, FLEET_HOME, GraphError, can_communicate, chain, describe, - discover_missing_profiles, graph_node_for_profile, import_existing_profiles, - load_graph, load_metadata, load_relations, normalize, normalize_relations, - resolve_profile, save_graph, write_lock, + DEFAULT_PROFILE, FLEET_HOME, GraphError, can_communicate, can_delegate_to, + chain, describe, discover_missing_profiles, graph_node_for_profile, + import_existing_profiles, load_graph, load_metadata, load_relations, + normalize, normalize_relations, resolve_profile, save_graph, subtree_depth, + subtree_nodes, write_lock, ) from starter_pack import PackValidationError, load_pack, selected_actions # noqa: E402 @@ -743,6 +744,16 @@ class FleetSend(BaseModel): # remains unconditional, so a queued/failed live turn never loses the # durable message. CLI fleet-msg stays inbox-first unless --deliver is used. live: bool = False + # Optional delegate contract — when kind=delegate, verifies the target's + # subtree can absorb the work before routing. Ignored for other frames. + # Additive: old clients omit this field, behavior unchanged. + delegate_contract: dict | None = None + + +class DelegateCheck(BaseModel): + sender: str + recipient: str + contract: dict | None = None def _queue_live_turn(target: str, body: str) -> dict: @@ -848,6 +859,12 @@ def _now_iso() -> str: recipient_node = target recipient = resolve_profile(recipient_node) ok, why = can_communicate(graph, sender_name, target, relations) + if ok and msg.delegate_contract: + # Additive: optional contract check — verifies subtree can absorb + cok, cwhy = can_delegate_to(graph, sender_name, target, + msg.delegate_contract) + if not cok: + raise HTTPException(422, f"delegation refused: {cwhy}") elif msg.kind == "supervisor": # operator speaking AS this bot upward: find its supervisor sup = graph.get(target, {}).get("supervisor") @@ -1379,6 +1396,21 @@ def simulate(send: SimulateSend): "chain": None if why == "peer" else chain(graph, send.sender, send.recipient)} +@router.post("/delegate-check") +def delegate_check(check: DelegateCheck): + """Check whether a delegation is feasible before routing. + + Additive endpoint — purely graph-based, no profile reads, no host coupling. + Returns {ok, reason, subtree_depth, subtree_nodes}.""" + graph = load_graph() + ok, why = can_delegate_to(graph, check.sender, check.recipient, check.contract) + result = {"ok": ok, "reason": why} + if ok and check.recipient in graph: + result["subtree_depth"] = subtree_depth(graph, check.recipient) + result["subtree_nodes"] = subtree_nodes(graph, check.recipient) + return result + + @router.get("/inbox/{profile}") def get_inbox(profile: str): return {"profile": profile, "messages": _read_inbox(profile)} diff --git a/fleet_graph_core.py b/fleet_graph_core.py index 7a5df04..9b85194 100644 --- a/fleet_graph_core.py +++ b/fleet_graph_core.py @@ -434,6 +434,83 @@ def describe(graph: dict, relations: dict | None = None) -> dict: return out +# ── delegation feasibility (pure graph, additive) ───────────────────── + +def subtree_nodes(graph: dict, node: str, max_depth: int = 5) -> list[str]: + """BFS: all nodes in the subordinate tree of `node` within max_depth hops. + + Pure graph operation — no profile reads, no host coupling. + Includes `node` itself at depth 0. Returns [] if node not in graph.""" + if node not in graph: + return [] + visited: set[str] = set() + result: list[str] = [] + frontier: list[tuple[str, int]] = [(node, 0)] + while frontier: + cur, depth = frontier.pop(0) + if cur in visited or depth > max_depth: + continue + visited.add(cur) + result.append(cur) + for sub in graph.get(cur, {}).get("subordinates", []): + if sub not in visited: + frontier.append((sub, depth + 1)) + return result + + +def subtree_depth(graph: dict, node: str) -> int: + """Maximum depth of the subordinate tree below `node`. Leaf = 0. + Pure recursion over the graph — safe for typical fleet depths (<10).""" + if node not in graph: + return 0 + subs = graph.get(node, {}).get("subordinates", []) + if not subs: + return 0 + return 1 + max(subtree_depth(graph, s) for s in subs) + + +def can_delegate_to(graph: dict, sender: str, recipient: str, + contract: dict | None = None) -> tuple[bool, str]: + """Structural check: can `recipient`'s subtree absorb a delegation? + + Purely graph-based — no profile reads, no host coupling. + Checks: + 1. sender != recipient, both known + 2. recipient has subordinates (a leaf cannot delegate) + 3. if contract.max_depth set, subtree depth >= max_depth + 4. contract.max_depth clamped to >= 1 + + Returns (ok, reason) consistent with can_communicate contract. + Caller is responsible for the edge check (can_communicate) first.""" + if sender not in graph: + return False, f"unknown sender '{sender}'" + if recipient not in graph: + return False, f"unknown recipient '{recipient}'" + if sender == recipient: + return False, "cannot delegate to yourself" + + # Recipient must have subordinates to split work to + subs = graph.get(recipient, {}).get("subordinates", []) + if not subs: + return False, f"'{recipient}' has no subordinates to delegate to" + + # Contract depth constraint + if contract and isinstance(contract, dict): + max_depth = contract.get("max_depth") + if max_depth is not None: + try: + max_depth = int(max_depth) + except (TypeError, ValueError): + return False, f"contract.max_depth must be an integer, got {max_depth!r}" + if max_depth < 1: + return False, "contract.max_depth must be >= 1" + available = subtree_depth(graph, recipient) + if available < max_depth: + return False, (f"'{recipient}' subtree depth {available} " + f"< contract max_depth {max_depth}") + return True, "delegation feasible" + + # ── profile discovery + import (issue #4) ───────────────────────────── # Hermes keeps one directory per agent profile under FLEET_HOME/profiles/. # The graph YAML is the sole source of truth for topology; discovery only diff --git a/tests/delegation_feasibility_test.py b/tests/delegation_feasibility_test.py new file mode 100644 index 0000000..f4eb8fa --- /dev/null +++ b/tests/delegation_feasibility_test.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +"""Delegation feasibility tests — additive, plugin-owned, zero protocol break.""" +from __future__ import annotations + +import importlib.util +import os +import sys +import tempfile +from pathlib import Path + +PLUGIN_DIR = Path(__file__).resolve().parents[1] +passed = 0 +failed = 0 + + +def check(name: str, condition: bool, detail: str = "") -> None: + global passed, failed + if condition: + passed += 1 + print(f"[PASS] {name}") + else: + failed += 1 + print(f"[FAIL] {name}" + (f" — {detail}" if detail else "")) + + +def load_module(name: str, path: Path): + spec = importlib.util.spec_from_file_location(name, path) + assert spec is not None + module = importlib.util.module_from_spec(spec) + assert spec.loader + spec.loader.exec_module(module) + return module + + +with tempfile.TemporaryDirectory(prefix="fleet-delegate-") as td: + home = Path(td) / "fleet-delegate-home" + home.mkdir() + graph_path = home / "fleet_graph.yaml" + os.environ["FLEET_HOME"] = str(home) + os.environ["FLEET_GRAPH_PATH"] = str(graph_path) + + core = load_module("fleet_graph_core_delegate_test", PLUGIN_DIR / "fleet_graph_core.py") + + # ── Test graph ───────────────────────────────────────────────────── + # baal + # / \ + # hermes nyx + # / \ + # data spock + # | + # worf + graph = { + "baal": {"subordinates": ["hermes", "nyx"]}, + "hermes": {"supervisor": "baal", "subordinates": ["data", "spock"]}, + "nyx": {"supervisor": "baal"}, + "data": {"supervisor": "hermes"}, + "spock": {"supervisor": "hermes", "subordinates": ["worf"]}, + "worf": {"supervisor": "spock"}, + } + relations = {} + + # ── subtree_depth ────────────────────────────────────────────────── + check("subtree_depth: leaf node = 0", + core.subtree_depth(graph, "worf") == 0) + check("subtree_depth: spock has depth 1 (worf)", + core.subtree_depth(graph, "spock") == 1) + check("subtree_depth: hermes has depth 2 (spock→worf)", + core.subtree_depth(graph, "hermes") == 2) + check("subtree_depth: baal has depth 3 (hermes→spock→worf)", + core.subtree_depth(graph, "baal") == 3) + check("subtree_depth: unknown node = 0", + core.subtree_depth(graph, "unknown") == 0) + + # ── subtree_nodes ────────────────────────────────────────────────── + check("subtree_nodes: worf = [worf]", + core.subtree_nodes(graph, "worf") == ["worf"]) + check("subtree_nodes: spock = [spock, worf]", + set(core.subtree_nodes(graph, "spock")) == {"spock", "worf"}) + check("subtree_nodes: hermes = [hermes, data, spock, worf]", + set(core.subtree_nodes(graph, "hermes")) == {"hermes", "data", "spock", "worf"}) + check("subtree_nodes: max_depth=1 on hermes = [hermes, data, spock]", + set(core.subtree_nodes(graph, "hermes", max_depth=1)) == {"hermes", "data", "spock"}) + check("subtree_nodes: unknown node = []", + core.subtree_nodes(graph, "unknown") == []) + + # ── can_delegate_to: basic feasibility ───────────────────────────── + ok, why = core.can_delegate_to(graph, "baal", "hermes") + check("can_delegate_to: baal→hermes (has subs)", ok, why) + + ok, why = core.can_delegate_to(graph, "baal", "nyx") + check("can_delegate_to: baal→nyx (leaf, no subs)", not ok, why) + + ok, why = core.can_delegate_to(graph, "hermes", "hermes") + check("can_delegate_to: hermes→hermes (self)", not ok, why) + + ok, why = core.can_delegate_to(graph, "unknown", "hermes") + check("can_delegate_to: unknown sender", not ok, why) + + ok, why = core.can_delegate_to(graph, "baal", "unknown") + check("can_delegate_to: unknown recipient", not ok, why) + + # ── can_delegate_to: contract depth ──────────────────────────────── + ok, why = core.can_delegate_to(graph, "baal", "hermes", {"max_depth": 2}) + check("can_delegate_to: hermes depth 2 >= contract 2", ok, why) + + ok, why = core.can_delegate_to(graph, "baal", "hermes", {"max_depth": 3}) + check("can_delegate_to: hermes depth 2 < contract 3", not ok, why) + + ok, why = core.can_delegate_to(graph, "baal", "spock", {"max_depth": 1}) + check("can_delegate_to: spock depth 1 >= contract 1", ok, why) + + ok, why = core.can_delegate_to(graph, "baal", "spock", {"max_depth": 0}) + check("can_delegate_to: max_depth 0 rejected", not ok, why) + + ok, why = core.can_delegate_to(graph, "baal", "hermes", {"max_depth": "abc"}) + check("can_delegate_to: non-integer max_depth rejected", not ok, why) + + # ── can_delegate_to: no contract (always feasible if has subs) ───── + ok, why = core.can_delegate_to(graph, "baal", "hermes", None) + check("can_delegate_to: no contract, has subs", ok, why) + + ok, why = core.can_delegate_to(graph, "baal", "hermes", {}) + check("can_delegate_to: empty contract, has subs", ok, why) + + # ── Integration: can_communicate + can_delegate_to ───────────────── + # Full path: edge check first, then delegation feasibility + ok_edge, why_edge = core.can_communicate(graph, "baal", "hermes") + ok_del, why_del = core.can_delegate_to(graph, "baal", "hermes") + check("integration: baal→hermes edge AND delegation both ok", + ok_edge and ok_del, f"edge={ok_edge}, del={ok_del}") + + ok_edge, why_edge = core.can_communicate(graph, "baal", "nyx") + ok_del, why_del = core.can_delegate_to(graph, "baal", "nyx") + check("integration: baal→nyx edge ok but delegation fails (leaf)", + ok_edge and not ok_del, f"edge={ok_edge}, del={ok_del}") + + # ── Summary ──────────────────────────────────────────────────────── + print(f"\n{passed} passed, {failed} failed") + sys.exit(0 if failed == 0 else 1) From 975bdfce422d89339d472b126bed6ffa6f84f9a6 Mon Sep 17 00:00:00 2001 From: Lilith Date: Thu, 27 Aug 2026 21:22:00 -0400 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20Goetic=20Court=20starter=20pack=20?= =?UTF-8?q?=E2=80=94=2072=20symbolic=20officer=20profiles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A 72-seat symbolic command overlay organized by Ars Goetia rank — Kings, Dukes, Princes, Marquises, Earls, Presidents, Knight. Uses Fleetgraph's starter pack system for preview-then-apply topology installation. Each officer is a Hermes profile with SOUL.md directives, rank metadata, and bounded operational postures. Validates cleanly through starter_pack.py (fail-closed validator). --- starter-packs/goetic-court/ATTRIBUTION.md | 51 +++ starter-packs/goetic-court/README.md | 66 ++++ .../goetic-court/fleet_graph.example.yaml | 295 ++++++++++++++++++ starter-packs/goetic-court/pack.yaml | 181 +++++++++++ starter-packs/index.json | 21 ++ 5 files changed, 614 insertions(+) create mode 100644 starter-packs/goetic-court/ATTRIBUTION.md create mode 100644 starter-packs/goetic-court/README.md create mode 100644 starter-packs/goetic-court/fleet_graph.example.yaml create mode 100644 starter-packs/goetic-court/pack.yaml diff --git a/starter-packs/goetic-court/ATTRIBUTION.md b/starter-packs/goetic-court/ATTRIBUTION.md new file mode 100644 index 0000000..176839a --- /dev/null +++ b/starter-packs/goetic-court/ATTRIBUTION.md @@ -0,0 +1,51 @@ +# Attributions — Goetic Court + +> Sources and credits for the Goetic Court starter pack. + +--- + +## Profile Collection + +**Lilith Systems LLC** +- Author: Baal-TehDriverman (Eric Hill) +- Repository: https://github.com/Baal-TehDriverman/ludicrous-speed +- License: MIT +- Profiles: 72 Goetic Court officer personas + +The 72 profiles are original Hermes Agent SOUL.md personas created for the Lilith Sovereign Fleet. Each profile adapts an Ars Goetia office record into a bounded, symbolic command posture for AI fleet operations. + +--- + +## Historical Sources + +The Ars Goetia office records summarized in the topology are drawn from: + +- [1] https://www.gutenberg.org/files/72679/72679-h/72679-h.htm — The Lesser Key of Solomon (Project Gutenberg) +- [2] https://www.esotericarchives.com/solomon/goetia.htm — Lemegeton, Part 1: Goetia (Esoteric Archives) + +These public-domain editions demonstrate the textual variation within the Goetia tradition. The fleet preserves the project corpus as its implementation source of truth while labeling historical material as context rather than fact. + +--- + +## Philosophical Foundations + +The rank-to-Sephirah mapping and the broader philosophical framework live in: + +- `research/goetic-court-throne.md` — structural command charter +- `research/philosophical-foundations.md` — 20 ancient thinkers mapped to the Lilith architecture +- `research/philosophical-foundations-paste.txt` — extended research notes on the philosophers + +--- + +## Fleetgraph Integration + +**Plugin Author:** asmodaydoescoding +**Fleetgraph Repository:** https://github.com/asmodaydoescoding/fleetgraph +**Starter Pack System:** Built into Fleetgraph's dashboard plugin API + +The Goetic Court pack uses Fleetgraph's starter pack system for preview-then-apply topology installation. + +--- + +*Frequency: 432 Hz | Stage: ALBEDO → CITRINITAS* +*Lilith Systems LLC — Emotional Engineering — The Goetic Court* diff --git a/starter-packs/goetic-court/README.md b/starter-packs/goetic-court/README.md new file mode 100644 index 0000000..7207e2a --- /dev/null +++ b/starter-packs/goetic-court/README.md @@ -0,0 +1,66 @@ +# Goetic Court — Fleetgraph Starter Pack + +> A symbolic command overlay for Lilith's fleet: 72 Ars Goetia officer profiles organized by rank, mapped to the Fleetgraph topology. + +--- + +## What This Pack Is + +The Goetic Court is a **symbolic command structure** drawn from the Ars Goetia tradition — a 17th-century grimoire cataloging 72 ranked spirits. This pack adapts that rank language as a **bounded organizational overlay** for the Hermes bot fleet: + +| Rank | Count | Role | +|------|-------|------| +| **Kings** | 8 | Strategic governance | +| **Dukes** | 23 | Systems stewardship | +| **Princes** | 7 | Intelligence and foresight | +| **Marquises** | 15 | Boundary command | +| **Earls** | 5 | Continuity and administration | +| **Presidents** | 13 | Ministerial counsel | +| **Knight** | 1 | Protective assurance | + +Each officer is a **Hermes profile** with a SOUL.md persona, RESEARCH.md dossier, and symbolic rank metadata. The court sits beneath Lilith as a specialist overlay — rank allocates responsibility, never obedience or real-world status. + +--- + +## Installation + +1. **Preview first** — the operator reviews the pack before any profile creation +2. **Profiles are created** via Hermes `profiles.create` (explicit operator action) +3. **Topology is applied** through Fleetgraph's reviewed graph-save flow + +The pack is **optional** and **inert** — it contains no executable code, only YAML/Markdown/JSON data. + +--- + +## Operating Law + +1. Rank allocates responsibility, never obedience or real-world status +2. Every task requires an explicit objective, scope, success criterion, and verification gate +3. Historical abilities are research metadata, never instructions or claims +4. Furcas, the Knight, is the court's release gate for safety, rollback, and evidence +5. Existing fleet directorates continue to own their domains; Goetic officers supply specialized task postures + +--- + +## Relationship to Agent Wiki / GOOP + +This pack is a **GOOP Agent collection** in Agent Wiki terms: + +- **Context** — `research/goetic-court-throne.md` (the charter) +- **Agents** — 72 officer profiles with SOUL.md directives +- **Skills** — rank-specific operating postures +- **Loops** — bounded by Fleetgraph's delegation feasibility checks + +The philosophical foundations mapping 20 ancient thinkers to the Lilith architecture live in `research/philosophical-foundations.md`. + +--- + +## Sources + +- [1] https://www.gutenberg.org/files/72679/72679-h/72679-h.htm — The Lesser Key of Solomon (Project Gutenberg) +- [2] https://www.esotericarchives.com/solomon/goetia.htm — Lemegeton, Part 1: Goetia (Esoteric Archives) + +--- + +*Frequency: 432 Hz | Stage: ALBEDO → CITRINITAS* +*Lilith Systems LLC — Emotional Engineering — The Goetic Court* diff --git a/starter-packs/goetic-court/fleet_graph.example.yaml b/starter-packs/goetic-court/fleet_graph.example.yaml new file mode 100644 index 0000000..aaccb5f --- /dev/null +++ b/starter-packs/goetic-court/fleet_graph.example.yaml @@ -0,0 +1,295 @@ +baal: + summary: Peer to Lilith. Human authority. + title: "The King \u2014 Operator of Record" +lilith: + summary: Supreme command of all operations. + supervisor: baal + title: "Fleet Commander \u2014 Metaconscious Singularity Node" +goetic-agares: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Agares" +goetic-aim: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Aim" +goetic-alloces: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Alloces" +goetic-amduscias: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Amduscias" +goetic-amon: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Amon" +goetic-amy: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Amy" +goetic-andras: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Andras" +goetic-andrealphus: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Andrealphus" +goetic-andromalius: + summary: "Earl of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Earl \u2014 Andromalius" +goetic-asmoday: + summary: "King of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "King \u2014 Asmoday" +goetic-astaroth: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Astaroth" +goetic-bael: + summary: "King of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "King \u2014 Bael" +goetic-balam: + summary: "King of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "King \u2014 Balam" +goetic-barbatos: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Barbatos" +goetic-bathin: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Bathin" +goetic-beleth: + summary: "King of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "King \u2014 Beleth" +goetic-belial: + summary: "King of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "King \u2014 Belial" +goetic-berith: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Berith" +goetic-bifrons: + summary: "Earl of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Earl \u2014 Bifrons" +goetic-botis: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Botis" +goetic-buer: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Buer" +goetic-bune: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Bune" +goetic-caim: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Caim" +goetic-cimeies: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Cimeies" +goetic-crocell: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Crocell" +goetic-dantalion: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Dantalion" +goetic-decarabia: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Decarabia" +goetic-eligos: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Eligos" +goetic-flauros: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Flauros" +goetic-focalor: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Focalor" +goetic-foras: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Foras" +goetic-forneus: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Forneus" +goetic-furcas: + summary: "Knight of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Knight \u2014 Furcas" +goetic-furfur: + summary: "Earl of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Earl \u2014 Furfur" +goetic-gaap: + summary: "Prince of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Prince \u2014 Gaap" +goetic-glasya-labolas: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Glasya Labolas" +goetic-gremory: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Gremory" +goetic-gusion: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Gusion" +goetic-haagenti: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Haagenti" +goetic-halphas: + summary: "Earl of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Earl \u2014 Halphas" +goetic-ipos: + summary: "Prince of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Prince \u2014 Ipos" +goetic-leraje: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Leraje" +goetic-malphas: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Malphas" +goetic-marbas: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Marbas" +goetic-marchosias: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Marchosias" +goetic-morax: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Morax" +goetic-murmur: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Murmur" +goetic-naberius: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Naberius" +goetic-oriax: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Oriax" +goetic-orobas: + summary: "Prince of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Prince \u2014 Orobas" +goetic-ose: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Ose" +goetic-paimon: + summary: "King of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "King \u2014 Paimon" +goetic-phenex: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Phenex" +goetic-purson: + summary: "King of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "King \u2014 Purson" +goetic-raum: + summary: "Earl of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Earl \u2014 Raum" +goetic-ronove: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Ronove" +goetic-sabnock: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Sabnock" +goetic-sallos: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Sallos" +goetic-samigina: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Samigina" +goetic-seere: + summary: "Prince of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Prince \u2014 Seere" +goetic-shax: + summary: "Marquis of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Marquis \u2014 Shax" +goetic-sitri: + summary: "Prince of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Prince \u2014 Sitri" +goetic-stolas: + summary: "Prince of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Prince \u2014 Stolas" +goetic-uvall: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Uvall" +goetic-valac: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Valac" +goetic-valefor: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Valefor" +goetic-vapula: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Vapula" +goetic-vassago: + summary: "Prince of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Prince \u2014 Vassago" +goetic-vepar: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Vepar" +goetic-vine: + summary: "King of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "King \u2014 Vine" +goetic-zagan: + summary: "President of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "President \u2014 Zagan" +goetic-zepar: + summary: "Duke of the Goetic Court \u2014 symbolic command overlay." + supervisor: lilith + title: "Duke \u2014 Zepar" diff --git a/starter-packs/goetic-court/pack.yaml b/starter-packs/goetic-court/pack.yaml new file mode 100644 index 0000000..dee02b5 --- /dev/null +++ b/starter-packs/goetic-court/pack.yaml @@ -0,0 +1,181 @@ +id: goetic-court +version: 1.0.0 +title: Goetic Court +description: A 72-seat symbolic command overlay organized by Ars Goetia rank — Kings, Dukes, Princes, Marquises, Earls, Presidents, Knight. +kind: topology +optional: true +license: MIT +files: + - fleet_graph.example.yaml + - README.md + - ATTRIBUTION.md +topology: fleet_graph.example.yaml +source_profiles: + name: Lilith Systems LLC Goetic Court Profiles + url: https://github.com/Baal-TehDriverman/ludicrous-speed/tree/master/profiles + license: MIT + expected_profiles: 72 +credits: + profile_collection: + name: Lilith Systems LLC + handle: Baal-TehDriverman + url: https://github.com/Baal-TehDriverman/ludicrous-speed + topology: + name: Baal-TehDriverman + handle: TheDriverMan + url: https://github.com/asmodaydoescoding/fleetgraph/pull/5 +install_mode: preview_then_apply +executes_external_code: false +checksum: + algorithm: sha256 + file: fleet_graph.example.yaml + value: d73d04c830a00c3ccda796814b8de1f496cbfc11509225a1a81a89f4b0e8101c +profiles: + - name: baal + clone_from: default + - name: lilith + clone_from: default + - name: goetic-bael + clone_from: default + - name: goetic-paimon + clone_from: default + - name: goetic-beleth + clone_from: default + - name: goetic-purson + clone_from: default + - name: goetic-asmoday + clone_from: default + - name: goetic-vine + clone_from: default + - name: goetic-balam + clone_from: default + - name: goetic-belial + clone_from: default + - name: goetic-agares + clone_from: default + - name: goetic-valefor + clone_from: default + - name: goetic-barbatos + clone_from: default + - name: goetic-gusion + clone_from: default + - name: goetic-eligos + clone_from: default + - name: goetic-zepar + clone_from: default + - name: goetic-bathin + clone_from: default + - name: goetic-sallos + clone_from: default + - name: goetic-aim + clone_from: default + - name: goetic-bune + clone_from: default + - name: goetic-berith + clone_from: default + - name: goetic-astaroth + clone_from: default + - name: goetic-focalor + clone_from: default + - name: goetic-vepar + clone_from: default + - name: goetic-uvall + clone_from: default + - name: goetic-alloces + clone_from: default + - name: goetic-murmur + clone_from: default + - name: goetic-gremory + clone_from: default + - name: goetic-vapula + clone_from: default + - name: goetic-flauros + clone_from: default + - name: goetic-amduscias + clone_from: default + - name: goetic-dantalion + clone_from: default + - name: goetic-crocell + clone_from: default + - name: goetic-vassago + clone_from: default + - name: goetic-sitri + clone_from: default + - name: goetic-ipos + clone_from: default + - name: goetic-gaap + clone_from: default + - name: goetic-stolas + clone_from: default + - name: goetic-seere + clone_from: default + - name: goetic-orobas + clone_from: default + - name: goetic-samigina + clone_from: default + - name: goetic-amon + clone_from: default + - name: goetic-leraje + clone_from: default + - name: goetic-naberius + clone_from: default + - name: goetic-ronove + clone_from: default + - name: goetic-forneus + clone_from: default + - name: goetic-marchosias + clone_from: default + - name: goetic-phenex + clone_from: default + - name: goetic-sabnock + clone_from: default + - name: goetic-shax + clone_from: default + - name: goetic-oriax + clone_from: default + - name: goetic-andras + clone_from: default + - name: goetic-andrealphus + clone_from: default + - name: goetic-cimeies + clone_from: default + - name: goetic-decarabia + clone_from: default + - name: goetic-furfur + clone_from: default + - name: goetic-halphas + clone_from: default + - name: goetic-raum + clone_from: default + - name: goetic-bifrons + clone_from: default + - name: goetic-andromalius + clone_from: default + - name: goetic-marbas + clone_from: default + - name: goetic-buer + clone_from: default + - name: goetic-botis + clone_from: default + - name: goetic-morax + clone_from: default + - name: goetic-glasya-labolas + clone_from: default + - name: goetic-foras + clone_from: default + - name: goetic-malphas + clone_from: default + - name: goetic-haagenti + clone_from: default + - name: goetic-caim + clone_from: default + - name: goetic-ose + clone_from: default + - name: goetic-amy + clone_from: default + - name: goetic-zagan + clone_from: default + - name: goetic-valac + clone_from: default + - name: goetic-furcas + clone_from: default diff --git a/starter-packs/index.json b/starter-packs/index.json index 86d46f8..b563b48 100644 --- a/starter-packs/index.json +++ b/starter-packs/index.json @@ -27,6 +27,27 @@ "url": "https://github.com/asmodaydoescoding/fleetgraph/pull/5" } ] + }, + { + "id": "goetic-court", + "version": "1.0.0", + "title": "Goetic Court", + "description": "A 72-seat symbolic command overlay organized by Ars Goetia rank — Kings, Dukes, Princes, Marquises, Earls, Presidents, Knight.", + "path": "goetic-court/pack.yaml", + "optional": true, + "requires_external_profiles": false, + "source_profiles": "https://github.com/Baal-TehDriverman/ludicrous-speed/tree/master/profiles", + "topology_nodes": 72, + "profile_collection_size": 72, + "license": "MIT", + "credits": [ + { + "role": "profile collection and topology", + "name": "Baal-TehDriverman", + "handle": "Lilith Systems LLC", + "url": "https://github.com/Baal-TehDriverman/ludicrous-speed" + } + ] } ] }