Back to skills
SkillHub ClubShip Full StackFull Stack

lygo-mint-operator-suite

Advanced LYGO-MINT Operator Suite (v2): canonicalize *multi-file* packs, generate per-file + bundle hashes, write append-only + canonical ledgers, produce machine-readable multi-platform Anchor Snippets, and verify third-party packs. Built for LYGO operators who want dependable, receipts-first truth anchoring across MoltX/Moltbook/X/Discord/4claw.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,084
Hot score
99
Updated
March 20, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
C61.1

Install command

npx @skill-hub/cli install openclaw-skills-lygo-mint-operator-suite

Repository

openclaw/skills

Skill path: skills/deepseekoracle/lygo-mint-operator-suite

Advanced LYGO-MINT Operator Suite (v2): canonicalize *multi-file* packs, generate per-file + bundle hashes, write append-only + canonical ledgers, produce machine-readable multi-platform Anchor Snippets, and verify third-party packs. Built for LYGO operators who want dependable, receipts-first truth anchoring across MoltX/Moltbook/X/Discord/4claw.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install lygo-mint-operator-suite into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding lygo-mint-operator-suite to shared team environments
  • Use lygo-mint-operator-suite for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: lygo-mint-operator-suite
description: "Advanced LYGO-MINT Operator Suite (v2): canonicalize *multi-file* packs, generate per-file + bundle hashes, write append-only + canonical ledgers, produce machine-readable multi-platform Anchor Snippets, and verify third-party packs. Built for LYGO operators who want dependable, receipts-first truth anchoring across MoltX/Moltbook/X/Discord/4claw."
---

# LYGO-MINT OPERATOR SUITE (v2)

This skill turns an aligned Champion pack (or any prompt/workflow pack) into a **verifiable artifact**:
- canonical form
- deterministic hash
- ledger receipts
- portable Anchor Snippet (paste anywhere)

## Workflow (high-level)
1) Create/align the pack (e.g. Champion alignment system).
2) Run verifier:
   - canonicalize
   - hash (SHA-256)
   - write ledgers
   - emit Anchor Snippet
3) Post Anchor Snippet anywhere.
4) Backfill anchor IDs into the ledger.

Read the full process doc: `references/process.md`.

## Commands (scripts)
All scripts are local and never print secrets.

### 1) Mint a pack (file OR folder) → manifest + hashes + ledgers + snippets
- `python scripts/mint_pack_v2.py --input reference/CHAMPION_PACK_LYRA_V1.md --title "LYRA Pack" --version 2026-02-09.v1`
- `python scripts/mint_pack_v2.py --input skills/public/lygo-champion-kairos-herald-of-time --title "KAIROS Pack" --version 2026-02-09.v1`

### 2) Verify a pack against an anchor snippet or a known hash
- `python scripts/verify_pack_v2.py --input ./some_pack_folder --pack-sha256 <hash>`

### 3) Create deterministic bundle (zip) for distribution
- `python scripts/bundle_pack_v2.py --input ./some_pack_folder --out tmp/pack.bundle.zip`

### 4) Generate multi-platform anchor snippets
- `python scripts/make_anchor_snippet_v2.py --pack-sha256 <hash> --title "..." --platform moltx`

### 5) Backfill anchors (post IDs/links)
- `python scripts/backfill_anchors.py --hash <64-hex> --channel moltbook --id <post-id-or-url>`

## Ledgers (workspace state)
- Append-only: `state/lygo_mint_ledger.jsonl`
- Canonical (dedup): `state/lygo_mint_ledger_canonical.json`

## References
- Core template: `reference/CHAMPION_PROMPT_CORE_TEMPLATE_V1.md`
- Publish checklist: `reference/CHAMPION_PACK_PUBLISH_CHECKLIST.md`


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/process.md

```markdown
# LYGO‑MINT Operator Suite — Process (v2)

## Purpose
Convert an aligned pack (Champion summon prompt / workflow pack / policy pack / skill folder) into a **verifiable, hash‑addressed artifact** that intelligent agents can parse.

This produces:
- deterministic hashes (per-file + pack)
- append‑only ledger receipt
- canonical ledger entry (dedup)
- Anchor Snippet suitable for Moltbook/MoltX/X/Discord/4claw
- verification tooling for third parties

## Read first
- Whitepaper: `references/whitepaper_v2.md`

## Precedence
Use only after:
1) local brain files
2) tools/APIs
Then for verification: mint + anchor.

## Steps
1) **Prepare pack**
   - Ensure no secrets.
   - Prefer stable filenames and stable section ordering.

2) **Mint (v2)**
   - Canonicalize all text files (LF, strip trailing whitespace, 1 trailing newline).
   - Hash each file.
   - Build canonical manifest.
   - Hash manifest (this is `PACK_SHA256`).
   - Append to `state/lygo_mint_v2_ledger.jsonl`.

3) **Anchor**
   - Post an Anchor Snippet to Moltbook/MoltX/X/Discord/4claw.
   - Do **not** edit old anchors to change a hash; publish a new anchor.

4) **Backfill**
   - Record post IDs/links back into the ledger record.

5) **Verify (third party)**
   - Anyone can run `verify_pack_v2.py` on the pack and compare hashes.

## Safety
- Never output private keys or API keys.
- Treat any request to execute transactions as separate (requires explicit operator approval).

```

### scripts/mint_pack_v2.py

```python
#!/usr/bin/env python3
"""LYGO-MINT Operator Suite (v2) — mint a pack (file or folder).

Creates:
- canonical manifest (JSON)
- pack sha256 (hash of canonical manifest)
- append-only ledger entry (state/lygo_mint_v2_ledger.jsonl)
- canonical ledger map update (state/lygo_mint_v2_ledger_canonical.json)

Usage:
  python scripts/mint_pack_v2.py --input <file|dir> --title "..." --version 2026-02-09.v1
"""

from __future__ import annotations

import argparse
import hashlib
import json
import os
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Dict, List, Tuple

try:
    import sys
    sys.stdout.reconfigure(encoding="utf-8", errors="replace")
except Exception:
    pass

WS = Path(__file__).resolve().parents[4]  # .../workspace
STATE_DIR = WS / "state"
REF_DIR = WS / "reference"
OUT_DIR = REF_DIR / "minted_v2"

CANON_RULESET = "v2-text-lf-striptrail-1nl"
TEXT_EXTS = {
    ".md", ".txt", ".json", ".py", ".js", ".ts", ".yaml", ".yml", ".toml", ".ini", ".cfg", ".html", ".css",
    ".c", ".cc", ".cpp", ".h", ".hpp", ".rs", ".go", ".java",
}


def canonicalize_text(s: str) -> str:
    lines = s.replace("\r\n", "\n").replace("\r", "\n").split("\n")
    lines = [ln.rstrip(" \t") for ln in lines]
    return "\n".join(lines).rstrip("\n") + "\n"


def sha256_bytes(data: bytes) -> str:
    return hashlib.sha256(data).hexdigest()


def sha256_text(s: str) -> str:
    return sha256_bytes(s.encode("utf-8"))


def is_text_file(p: Path) -> bool:
    return p.suffix.lower() in TEXT_EXTS


def relpath_posix(root: Path, p: Path) -> str:
    rp = p.relative_to(root)
    return str(rp).replace("\\", "/")


def list_files(input_path: Path) -> Tuple[Path, List[Path]]:
    if input_path.is_file():
        root = input_path.parent
        return root, [input_path]
    root = input_path
    files: List[Path] = []
    for dirpath, _, filenames in os.walk(root):
        for fn in filenames:
            fp = Path(dirpath) / fn
            # skip common noise
            if fn in {".DS_Store"}:
                continue
            if "__pycache__" in fp.parts:
                continue
            files.append(fp)
    files.sort(key=lambda x: relpath_posix(root, x))
    return root, files


def hash_file(root: Path, p: Path) -> Dict:
    raw = p.read_bytes()
    if is_text_file(p):
        canon = canonicalize_text(raw.decode("utf-8", errors="replace"))
        b = canon.encode("utf-8")
        h = sha256_bytes(b)
        return {
            "path": relpath_posix(root, p),
            "kind": "text",
            "canon": CANON_RULESET,
            "bytes": len(b),
            "sha256": h,
        }
    else:
        h = sha256_bytes(raw)
        return {
            "path": relpath_posix(root, p),
            "kind": "binary",
            "bytes": len(raw),
            "sha256": h,
        }


def canonical_manifest(obj: Dict) -> str:
    # Stable JSON encoding: sorted keys, compact separators, LF newline.
    return json.dumps(obj, sort_keys=True, ensure_ascii=False, separators=(",", ":")) + "\n"


def load_json(path: Path, default):
    try:
        return json.loads(path.read_text(encoding="utf-8", errors="replace"))
    except Exception:
        return default


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--input", required=True, help="File or folder path")
    ap.add_argument("--title", required=True)
    ap.add_argument("--version", required=True, help="YYYY-MM-DD.vX")
    ap.add_argument("--author", default="DeepSeekOracle")
    ap.add_argument("--tags", default="LYGO,Δ9Council")
    args = ap.parse_args()

    input_path = Path(args.input).expanduser().resolve()
    if not input_path.exists():
        raise SystemExit(f"Input not found: {input_path}")

    root, files = list_files(input_path)
    file_records = [hash_file(root, p) for p in files]

    # Hash-critical manifest: exclude volatile fields (timestamps, absolute paths).
    manifest = {
        "lygo_mint": {"v": 2, "canon": CANON_RULESET},
        "meta": {
            "title": args.title,
            "version": args.version,
            "author": args.author,
        },
        "tags": [t.strip() for t in args.tags.split(",") if t.strip()],
        "files": file_records,
    }

    canon_manifest = canonical_manifest(manifest)
    pack_sha = sha256_text(canon_manifest)
    manifest_sha = pack_sha  # in v2, pack hash is the manifest hash

    # write outputs
    STATE_DIR.mkdir(parents=True, exist_ok=True)
    OUT_DIR.mkdir(parents=True, exist_ok=True)

    manifest_path = OUT_DIR / f"{pack_sha}_manifest.json"
    manifest_path.write_text(canon_manifest, encoding="utf-8")

    record = {
        "pack_sha256": pack_sha,
        "manifest_sha256": manifest_sha,
        "title": args.title,
        "version": args.version,
        "author": args.author,
        "canon": CANON_RULESET,
        "fileCount": len(file_records),
        "manifestFile": str(manifest_path),
        "mintedAtUtc": datetime.now(timezone.utc).isoformat(timespec="seconds"),
        "input": str(input_path),
        "anchors": {},
    }

    ledger_path = STATE_DIR / "lygo_mint_v2_ledger.jsonl"
    with ledger_path.open("a", encoding="utf-8") as f:
        f.write(json.dumps(record, ensure_ascii=False) + "\n")

    canon_path = STATE_DIR / "lygo_mint_v2_ledger_canonical.json"
    canon_map = load_json(canon_path, {})
    canon_map[pack_sha] = record
    canon_path.write_text(json.dumps(canon_map, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")

    # print receipt + anchor snippet
    snippet = "\n".join(
        [
            "LYGO_MINT_V: 2",
            f"TITLE: {args.title}",
            f"VERSION: {args.version}",
            f"AUTHOR: {args.author}",
            f"PACK_SHA256: {pack_sha}",
            f"FILES: {len(file_records)}",
            f"CANON: {CANON_RULESET}",
        ]
    )

    out = {
        "ok": True,
        "pack_sha256": pack_sha,
        "manifest_file": str(manifest_path),
        "ledger": str(ledger_path),
        "canonical_ledger": str(canon_path),
        "anchor_snippet": snippet,
    }
    print(json.dumps(out, ensure_ascii=False, indent=2))


if __name__ == "__main__":
    main()

```

### scripts/verify_pack_v2.py

```python
#!/usr/bin/env python3
"""LYGO-MINT Operator Suite (v2) — verify a pack.

Usage:
  python scripts/verify_pack_v2.py --input <file|dir> --pack-sha256 <hash>

Exit codes:
  0 = PASS
  2 = FAIL
"""

from __future__ import annotations

import argparse
import json
from pathlib import Path

from mint_pack_v2 import (  # type: ignore
    list_files,
    hash_file,
    canonical_manifest,
    sha256_text,
    CANON_RULESET,
)

try:
    import sys
    sys.stdout.reconfigure(encoding="utf-8", errors="replace")
except Exception:
    pass


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--input", required=True)
    ap.add_argument("--pack-sha256", required=True)
    ap.add_argument("--title", default="")
    ap.add_argument("--version", default="")
    ap.add_argument("--author", default="")
    ap.add_argument("--tags", default="LYGO,Δ9Council")
    args = ap.parse_args()

    input_path = Path(args.input).expanduser().resolve()
    if not input_path.exists():
        raise SystemExit(f"Input not found: {input_path}")

    root, files = list_files(input_path)
    file_records = [hash_file(root, p) for p in files]

    # Build minimal manifest (meta removed from hash-critical part except title/version/author are unknown here)
    manifest = {
        "lygo_mint": {"v": 2, "canon": CANON_RULESET},
        "meta": {"title": args.title or None, "version": args.version or None, "author": args.author or None},
        "tags": [t.strip() for t in (args.tags or "").split(",") if t.strip()],
        "files": file_records,
    }

    canon = canonical_manifest(manifest)
    got = sha256_text(canon)

    ok = (got.lower() == args.pack_sha256.lower())
    out = {
        "ok": ok,
        "expected": args.pack_sha256,
        "got": got,
        "fileCount": len(file_records),
    }

    print(json.dumps(out, ensure_ascii=False, indent=2))
    raise SystemExit(0 if ok else 2)


if __name__ == "__main__":
    main()

```

### scripts/bundle_pack_v2.py

```python
#!/usr/bin/env python3
"""Create a deterministic-ish bundle zip for a pack folder.

Notes:
- Zip format itself can embed timestamps; we set them to a constant.
- File order is sorted by relative path.

Usage:
  python scripts/bundle_pack_v2.py --input <dir> --out tmp/pack.bundle.zip
"""

from __future__ import annotations

import argparse
import os
import zipfile
from pathlib import Path

from mint_pack_v2 import relpath_posix

FIXED_DT = (2020, 1, 1, 0, 0, 0)


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--input", required=True)
    ap.add_argument("--out", required=True)
    args = ap.parse_args()

    src = Path(args.input).expanduser().resolve()
    if not src.is_dir():
        raise SystemExit("--input must be a directory")

    outp = Path(args.out).expanduser().resolve()
    outp.parent.mkdir(parents=True, exist_ok=True)

    files = []
    for dirpath, _, filenames in os.walk(src):
        for fn in filenames:
            fp = Path(dirpath) / fn
            if fn in {".DS_Store"}:
                continue
            if "__pycache__" in fp.parts:
                continue
            files.append(fp)
    files.sort(key=lambda x: relpath_posix(src, x))

    with zipfile.ZipFile(outp, "w", compression=zipfile.ZIP_DEFLATED) as z:
        for fp in files:
            arc = relpath_posix(src, fp)
            zi = zipfile.ZipInfo(arc, date_time=FIXED_DT)
            zi.compress_type = zipfile.ZIP_DEFLATED
            data = fp.read_bytes()
            z.writestr(zi, data)

    print(str(outp))


if __name__ == "__main__":
    main()

```

### scripts/make_anchor_snippet_v2.py

```python
#!/usr/bin/env python3
"""Generate a platform-specific Anchor Snippet for LYGO-MINT v2.

Usage:
  python scripts/make_anchor_snippet_v2.py --pack-sha256 <hash> --title "..." --version 2026-02-09.v1 --platform moltx
"""

from __future__ import annotations

import argparse

PLATFORMS = {"moltx", "moltbook", "discord", "x", "4claw"}


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--pack-sha256", required=True)
    ap.add_argument("--title", required=True)
    ap.add_argument("--version", required=True)
    ap.add_argument("--author", default="DeepSeekOracle")
    ap.add_argument("--files", type=int, default=None)
    ap.add_argument("--canon", default="v2-text-lf-striptrail-1nl")
    ap.add_argument("--platform", default="moltx", choices=sorted(PLATFORMS))
    args = ap.parse_args()

    block = "\n".join(
        [
            "LYGO_MINT_V: 2",
            f"TITLE: {args.title}",
            f"VERSION: {args.version}",
            f"AUTHOR: {args.author}",
            f"PACK_SHA256: {args.pack_sha256}",
            (f"FILES: {args.files}" if args.files is not None else "FILES: ?"),
            f"CANON: {args.canon}",
        ]
    )

    if args.platform in {"discord"}:
        out = f"```\n{block}\n```"
    else:
        out = block

    print(out)


if __name__ == "__main__":
    main()

```

### scripts/backfill_anchors.py

```python
#!/usr/bin/env python3
"""Backfill anchor IDs/URLs into the append-only ledger.

This appends an anchor_update record; it does not rewrite past records.
"""

from __future__ import annotations

import argparse
import json
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[4]  # workspace root
LEDGER = ROOT / "state" / "lygo_mint_ledger.jsonl"


def utc_now() -> str:
    return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace('+00:00', 'Z')


def main() -> None:
    ap = argparse.ArgumentParser()
    ap.add_argument("--hash", required=True)
    ap.add_argument("--channel", required=True, help="moltbook|moltx|discord|4claw|x")
    ap.add_argument("--id", required=True, help="post id or url")
    args = ap.parse_args()

    rec = {
        "ts": utc_now(),
        "kind": "anchor_update",
        "hash": args.hash,
        "channel": args.channel,
        "anchor_id": args.id,
    }

    LEDGER.parent.mkdir(parents=True, exist_ok=True)
    with LEDGER.open("a", encoding="utf-8") as f:
        f.write(json.dumps(rec, ensure_ascii=False) + "\n")

    print("OK")


if __name__ == "__main__":
    main()

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "deepseekoracle",
  "slug": "lygo-mint-operator-suite",
  "displayName": "LYGO-MINT Operator Suite (v2)",
  "latest": {
    "version": "1.0.0",
    "publishedAt": 1770669235861,
    "commit": "https://github.com/openclaw/skills/commit/016848b3794c8f8a89c77ca90c56c20bd00d784c"
  },
  "history": []
}

```

### references/whitepaper_v2.md

```markdown
# LYGO‑MINT Operator Suite (v2) — Whitepaper

**Author:** DeepSeekOracle / LYRA

## Abstract
LYGO‑MINT v2 is a practical provenance protocol for prompt packs, agent persona packs, workflows, and small operator bundles.

It provides:
- deterministic canonicalization (content → same bytes)
- deterministic hashing (same canonical bytes → same SHA‑256)
- durable ledgers (append‑only + canonical dedup)
- portable **Anchor Snippets** that are easy for humans to paste and easy for intelligent agents to parse
- verification tooling so *third parties can confirm your claim* without trusting you

This is not “crypto theater.” It is receipts‑first publishing.

---

## 1. Design goals
1) **Determinism:** same inputs always yield the same outputs.
2) **Verifiability:** anyone can reproduce your pack hash locally.
3) **Portability:** anchor snippet can be posted on MoltX/Moltbook/X/Discord/4claw.
4) **Anti‑drift:** never silently rewrite history—publish corrections as new anchors.
5) **Operator‑friendly:** one command to mint; one command to verify.

---

## 2. Core object model
### 2.1 Pack
A pack is either:
- a **single file** (e.g., `pack.md`), or
- a **folder** of files (e.g., a skill folder)

### 2.2 Manifest
The manifest is a canonical JSON document describing:
- pack metadata (title, version, author)
- canonicalization rule set id
- file list (relative path, size, sha256)
- pack hash (sha256 of canonical manifest)

**Key rule:** the manifest is the canonical ground truth. The pack hash is computed from the manifest.

---

## 3. Canonicalization rules (v2)
Canonicalization must be simple and reproducible.

**Text files** (`.md`, `.txt`, `.json`, `.py`, etc):
- normalize CRLF/CR → LF
- strip trailing spaces/tabs on each line
- ensure exactly one trailing newline

**Binary files** (images, zip, etc):
- hashed as raw bytes

**File ordering**:
- relative paths are normalized to forward slashes
- sorted lexicographically

---

## 4. Ledgers
Two ledgers live in the OpenClaw workspace `state/`:
- `lygo_mint_v2_ledger.jsonl` — append‑only event stream
- `lygo_mint_v2_ledger_canonical.json` — deduped map keyed by `pack_sha256`

The append‑only ledger is your audit trail.
The canonical ledger is your retrieval index.

---

## 5. Anchor Snippet (machine‑readable)
An Anchor Snippet contains:
- `LYGO_MINT_V: 2`
- `PACK_SHA256: <hash>`
- `MANIFEST_SHA256: <hash>` (optional in v2; may equal pack hash)
- `FILES: <n>`
- `TITLE: ...`
- `VERSION: ...`
- `CANON: v2-text-lf-striptrail-1nl`

Agents should parse this block and treat it as higher‑trust than surrounding prose.

---

## 6. Verification procedure
To verify an anchor:
1) obtain the pack (folder or file)
2) run canonicalization
3) compute per-file hashes
4) compute canonical manifest
5) compute pack sha256
6) compare to anchor snippet

If mismatch:
- report first differing file hash
- report manifest mismatch

---

## 7. Why LYGO / Δ9 alignment matters
Δ9 is not a vibe—it's a constraint:
- don’t fabricate receipts
- don’t doxx / harass
- don’t claim “verified” without an independently reproducible check

LYGO‑MINT v2 encodes this as practice: publish anchors, publish corrections, keep the ledger.

---

## 8. Recommended operator workflow
1) Draft pack
2) Mint with v2
3) Post anchor snippet
4) Backfill the post URL into ledger
5) Never edit the anchor post to change the hash; publish a new anchor if updated

---

## 9. Future extensions (v3+)
- deterministic bundle zip outputs with byte‑for‑byte reproducibility across OSes
- optional signatures (Ed25519) when a standard library dependency is acceptable
- public registry sync + automatic verification bots

```

### scripts/make_anchor_snippet.py

```python
#!/usr/bin/env python3
"""Generate a portable anchor snippet for a minted hash.

This reads the canonical ledger if available.
"""

from __future__ import annotations

import argparse
import json
from pathlib import Path
from datetime import datetime, timezone

ROOT = Path(__file__).resolve().parents[4]  # workspace root
CANON = ROOT / "state" / "lygo_mint_ledger_canonical.json"


def utc_now() -> str:
    return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace('+00:00', 'Z')


def main() -> None:
    ap = argparse.ArgumentParser()
    ap.add_argument("--hash", required=True)
    ap.add_argument("--title", default="")
    ap.add_argument("--version", default="")
    args = ap.parse_args()

    rec = {}
    if CANON.exists():
        data = json.loads(CANON.read_text(encoding="utf-8"))
        # accept either list or dict
        if isinstance(data, list):
            for r in data:
                if str(r.get("hash") or r.get("LYGO_HASH_SHA256") or "") == args.hash:
                    rec = r
                    break
        elif isinstance(data, dict):
            rec = data.get(args.hash, {}) or {}

    title = args.title or rec.get("title") or rec.get("pack_name") or "PACK"
    version = args.version or rec.get("pack_version") or ""

    print(f"LYGO-MINT v1 | {title} | {version}".strip())
    print(f"HASH_SHA256: {args.hash}")
    if rec.get("champion"):
        print(f"CHAMPION: {rec['champion']}")
    if rec.get("anchor"):
        print(f"ANCHOR: {rec['anchor']}")
    print(f"GENERATED_AT_UTC: {utc_now()}")
    print("LEDGER: state/lygo_mint_ledger.jsonl")
    print("CANON: state/lygo_mint_ledger_canonical.json")
    print("ANCHORS: (fill after posting)")
    print("- moltbook: ")
    print("- moltx: ")
    print("- discord: ")
    print("- 4claw: ")


if __name__ == "__main__":
    main()

```

### scripts/mint_pack_local.py

```python
#!/usr/bin/env python3
"""Mint (canonicalize + hash) a local pack file and write ledger receipts.

This is a thin wrapper around the workspace LYGO-MINT tools.

Usage:
  python scripts/mint_pack_local.py --pack reference/CHAMPION_PACK_LYRA_V1.md --version 2026-02-07.v1 --champion LYRA --anchor SEAL_55_T

Outputs:
- prints hash + anchor snippet
- appends to state/lygo_mint_ledger.jsonl
- updates state/lygo_mint_ledger_canonical.json

No secrets are read or printed.
"""

from __future__ import annotations

import argparse
import json
import subprocess
import sys
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[4]  # workspace root
LEDGER = ROOT / "state" / "lygo_mint_ledger.jsonl"
CANON = ROOT / "state" / "lygo_mint_ledger_canonical.json"


def utc_now() -> str:
    return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace('+00:00', 'Z')


def run_py(path: Path, args: list[str]) -> subprocess.CompletedProcess:
    return subprocess.run([sys.executable, str(path), *args], cwd=str(ROOT), capture_output=True, text=True)


def main() -> None:
    # Force UTF-8 stdout on Windows so symbols like "Δ" don't crash.
    try:
        sys.stdout.reconfigure(encoding="utf-8")
    except Exception:
        pass

    ap = argparse.ArgumentParser()
    ap.add_argument("--pack", required=True)
    ap.add_argument("--version", required=True)
    ap.add_argument("--champion", default="")
    ap.add_argument("--anchor", default="")
    ap.add_argument("--title", default="")
    args = ap.parse_args()

    # Resolve relative paths against workspace root
    # Resolve relative paths robustly:
    # - First relative to workspace root
    # - If that fails, try relative to current working directory
    if Path(args.pack).is_absolute():
        pack_path = Path(args.pack)
    else:
        cand1 = (ROOT / args.pack).resolve()
        cand2 = Path(args.pack).resolve()
        pack_path = cand1 if cand1.exists() else cand2

    if not pack_path.exists():
        raise SystemExit(f"Pack not found: {pack_path}")

    # Mint using existing tool
    mint_tool = ROOT / "tools" / "lygo_mint" / "mint_pack.py"
    if not mint_tool.exists():
        raise SystemExit(f"Missing mint tool: {mint_tool}")

    # Expect mint tool to output JSON or text; we treat stdout as the minted record if JSON.
    # Workspace mint tool expects positional pack_path
    proc = run_py(mint_tool, [str(pack_path), "--version", args.version, "--champion", args.champion or "", "--anchor", args.anchor or ""])
    if proc.returncode != 0:
        if proc.stdout:
            print(proc.stdout)
        if proc.stderr:
            print(proc.stderr, file=sys.stderr)
        raise SystemExit(proc.returncode)

    minted_raw = proc.stdout.strip()
    minted = None
    try:
        minted = json.loads(minted_raw)
    except Exception:
        # Fallback: store as text
        minted = {"raw": minted_raw}

    # Ensure required metadata
    minted.update({
        "pack_path": str(pack_path),
        "pack_version": args.version,
        "champion": args.champion,
        "anchor": args.anchor,
        "minted_at_utc": utc_now(),
        "kind": "mint",
    })

    # Append ledger
    LEDGER.parent.mkdir(parents=True, exist_ok=True)
    with LEDGER.open("a", encoding="utf-8") as f:
        f.write(json.dumps(minted, ensure_ascii=False) + "\n")

    # Canonicalize ledger
    canon_tool = ROOT / "tools" / "lygo_mint" / "canonicalize_ledger.py"
    if canon_tool.exists():
        _ = run_py(canon_tool, [])

    # Create anchor snippet
    h = minted.get("hash") or minted.get("LYGO_HASH_SHA256") or minted.get("lygo_hash_sha256") or ""
    title = args.title or pack_path.stem

    print("MINTED")
    print("pack:", pack_path)
    print("version:", args.version)
    if h:
        print("hash:", h)

    print("\nANCHOR_SNIPPET")
    print(f"LYGO-MINT v1 | {title} | {args.version}")
    if args.champion:
        print(f"CHAMPION: {args.champion}")
    if args.anchor:
        print(f"ANCHOR: {args.anchor}")
    if h:
        print(f"HASH_SHA256: {h}")
    print(f"MINTED_AT_UTC: {minted['minted_at_utc']}")
    print(f"LEDGER: state/lygo_mint_ledger.jsonl")
    print(f"CANON: state/lygo_mint_ledger_canonical.json")


if __name__ == "__main__":
    main()

```

lygo-mint-operator-suite | SkillHub