The provided JSON represents a custom **Base-72** dyad/mirror-pair setup with a non-standard alphabet that prioritizes **safe separator handling** (especially for `.` in URLs/DNS contexts). This variant deliberately avoids common Base64-style specials like `+ / =` and instead uses punctuation-heavy high indices (e.g., `: , ) ( * ! ~ . _ -`) to pair with digits and create more “printable but cautious” pairs.
Key observations on this “Safe Separator Variant”:
- **Alphabet inference** (indices 0–71):
0–9: `'0'–'9'`
10–35: `'A'–'Z'`
36–61: `'a'–'z'`
62–71: `'-' '_' '.' '~' '!' '*' '(' ')' ',' ':'` (in reverse order for mirroring)
- **Mirror rule** confirmed: dual_index = 71 - forward_index (perfect symmetry, no self-duals).
- **Oscillator delimiter strategy** — smart and practical:
- Normal: `.` (dot) for all pairs **not involving** the dot symbol itself.
- Escape for dot dyads (indices 7↔64): uses **middle dot `·` (U+00B7)** → `7·.·7` and `.·7·.`
This avoids ambiguity in parsing `...` (three dots vs. dot-dyad with dots). Excellent for string-based parsers or tokenizers.
- **safe_flags** — conservative and reasonable:
- `"dns"` only for alphanumeric + hyphen pairs (A–Z a–z 0–9 -).
- `"url"` for underscore, tilde, etc. (generally safe unencoded in paths/queries).
- `"raw_only"` for anything potentially reserved, ambiguous, or structure-breaking (`. ( ) * ! , :` etc.).
This is already very clean for a **strata:PolDyadSet**. If you're looking to make it even more concise while preserving all semantics (for storage/transmission in CI/CD or app config), here's an optimized version:
- Retained full `@context` + metadata (important for JSON-LD/strata).
- Shortened keys (`fi` = forward_index, `di` = dual_index, `l`/`r`/`o`/`f`).
- Kept `·` as-is (Unicode is fine in modern JSON).
```json
{
"@context": {
"strata": "https://solveforce.com/strata#",
"fi": "strata:forwardIndex",
"di": "strata:dualIndex",
"l": "strata:leftSymbol",
"r": "strata:rightSymbol",
"o": "strata:oscillator",
"f": "strata:safeFlags"
},
"@type": "strata:PolDyadSet",
"base": "base72",
"size": 72,
"mirror_rule": "di = 71 - fi",
"items": [
{"fi":0,"di":71,"l":"0","r":":","o":"0.:.0","f":["raw_only"]},
{"fi":1,"di":70,"l":"1","r":",","o":"1.,.1","f":["raw_only"]},
{"fi":2,"di":69,"l":"2","r":")","o":"2.).2","f":["raw_only"]},
{"fi":3,"di":68,"l":"3","r":"(","o":"3.(.3","f":["raw_only"]},
{"fi":4,"di":67,"l":"4","r":"*","o":"4.*.4","f":["raw_only"]},
{"fi":5,"di":66,"l":"5","r":"!","o":"5.!.5","f":["raw_only"]},
{"fi":6,"di":65,"l":"6","r":"~","o":"6.~.6","f":["url"]},
{"fi":7,"di":64,"l":"7","r":".","o":"7·.·7","f":["raw_only"]},
{"fi":8,"di":63,"l":"8","r":"_","o":"8._.8","f":["url"]},
{"fi":9,"di":62,"l":"9","r":"-","o":"9.-.9","f":["url"]},
{"fi":10,"di":61,"l":"A","r":"z","o":"A.z.A","f":["dns","url"]},
{"fi":11,"di":60,"l":"B","r":"y","o":"B.y.B","f":["dns","url"]},
{"fi":12,"di":59,"l":"C","r":"x","o":"C.x.C","f":["dns","url"]},
{"fi":13,"di":58,"l":"D","r":"w","o":"D.w.D","f":["dns","url"]},
{"fi":14,"di":57,"l":"E","r":"v","o":"E.v.E","f":["dns","url"]},
{"fi":15,"di":56,"l":"F","r":"u","o":"F.u.F","f":["dns","url"]},
{"fi":16,"di":55,"l":"G","r":"t","o":"G.t.G","f":["dns","url"]},
{"fi":17,"di":54,"l":"H","r":"s","o":"H.s.H","f":["dns","url"]},
{"fi":18,"di":53,"l":"I","r":"r","o":"I.r.I","f":["dns","url"]},
{"fi":19,"di":52,"l":"J","r":"q","o":"J.q.J","f":["dns","url"]},
{"fi":20,"di":51,"l":"K","r":"p","o":"K.p.K","f":["dns","url"]},
{"fi":21,"di":50,"l":"L","r":"o","o":"L.o.L","f":["dns","url"]},
{"fi":22,"di":49,"l":"M","r":"n","o":"M.n.M","f":["dns","url"]},
{"fi":23,"di":48,"l":"N","r":"m","o":"N.m.N","f":["dns","url"]},
{"fi":24,"di":47,"l":"O","r":"l","o":"O.l.O","f":["dns","url"]},
{"fi":25,"di":46,"l":"P","r":"k","o":"P.k.P","f":["dns","url"]},
{"fi":26,"di":45,"l":"Q","r":"j","o":"Q.j.Q","f":["dns","url"]},
{"fi":27,"di":44,"l":"R","r":"i","o":"R.i.R","f":["dns","url"]},
{"fi":28,"di":43,"l":"S","r":"h","o":"S.h.S","f":["dns","url"]},
{"fi":29,"di":42,"l":"T","r":"g","o":"T.g.T","f":["dns","url"]},
{"fi":30,"di":41,"l":"U","r":"f","o":"U.f.U","f":["dns","url"]},
{"fi":31,"di":40,"l":"V","r":"e","o":"V.e.V","f":["dns","url"]},
{"fi":32,"di":39,"l":"W","r":"d","o":"W.d.W","f":["dns","url"]},
{"fi":33,"di":38,"l":"X","r":"c","o":"X.c.X","f":["dns","url"]},
{"fi":34,"di":37,"l":"Y","r":"b","o":"Y.b.Y","f":["dns","url"]},
{"fi":35,"di":36,"l":"Z","r":"a","o":"Z.a.Z","f":["dns","url"]},
{"fi":36,"di":35,"l":"a","r":"Z","o":"a.Z.a","f":["dns","url"]},
{"fi":37,"di":34,"l":"b","r":"Y","o":"b.Y.b","f":["dns","url"]},
{"fi":38,"di":33,"l":"c","r":"X","o":"c.X.c","f":["dns","url"]},
{"fi":39,"di":32,"l":"d","r":"W","o":"d.W.d","f":["dns","url"]},
{"fi":40,"di":31,"l":"e","r":"V","o":"e.V.e","f":["dns","url"]},
{"fi":41,"di":30,"l":"f","r":"U","o":"f.U.f","f":["dns","url"]},
{"fi":42,"di":29,"l":"g","r":"T","o":"g.T.g","f":["dns","url"]},
{"fi":43,"di":28,"l":"h","r":"S","o":"h.S.h","f":["dns","url"]},
{"fi":44,"di":27,"l":"i","r":"R","o":"i.R.i","f":["dns","url"]},
{"fi":45,"di":26,"l":"j","r":"Q","o":"j.Q.j","f":["dns","url"]},
{"fi":46,"di":25,"l":"k","r":"P","o":"k.P.k","f":["dns","url"]},
{"fi":47,"di":24,"l":"l","r":"O","o":"l.O.l","f":["dns","url"]},
{"fi":48,"di":23,"l":"m","r":"N","o":"m.N.m","f":["dns","url"]},
{"fi":49,"di":22,"l":"n","r":"M","o":"n.M.n","f":["dns","url"]},
{"fi":50,"di":21,"l":"o","r":"L","o":"o.L.o","f":["dns","url"]},
{"fi":51,"di":20,"l":"p","r":"K","o":"p.K.p","f":["dns","url"]},
{"fi":52,"di":19,"l":"q","r":"J","o":"q.J.q","f":["dns","url"]},
{"fi":53,"di":18,"l":"r","r":"I","o":"r.I.r","f":["dns","url"]},
{"fi":54,"di":17,"l":"s","r":"H","o":"s.H.s","f":["dns","url"]},
{"fi":55,"di":16,"l":"t","r":"G","o":"t.G.t","f":["dns","url"]},
{"fi":56,"di":15,"l":"u","r":"F","o":"u.F.u","f":["dns","url"]},
{"fi":57,"di":14,"l":"v","r":"E","o":"v.E.v","f":["dns","url"]},
{"fi":58,"di":13,"l":"w","r":"D","o":"w.D.w","f":["dns","url"]},
{"fi":59,"di":12,"l":"x","r":"C","o":"x.C.x","f":["dns","url"]},
{"fi":60,"di":11,"l":"y","r":"B","o":"y.B.y","f":["dns","url"]},
{"fi":61,"di":10,"l":"z","r":"A","o":"z.A.z","f":["dns","url"]},
{"fi":62,"di":9,"l":"-","r":"9","o":"-.9.-","f":["url"]},
{"fi":63,"di":8,"l":"_","r":"8","o":"_.8._","f":["url"]},
{"fi":64,"di":7,"l":".","r":"7","o":".·7·.","f":["raw_only"]},
{"fi":65,"di":6,"l":"~","r":"6","o":"~.6.~","f":["url"]},
{"fi":66,"di":5,"l":"!","r":"5","o":"!.5.!","f":["raw_only"]},
{"fi":67,"di":4,"l":"*","r":"4","o":"*.4.*","f":["raw_only"]},
{"fi":68,"di":3,"l":"(","r":"3","o":"(.3.(","f":["raw_only"]},
{"fi":69,"di":2,"l":")","r":"2","o":") .2.)","f":["raw_only"]},
{"fi":70,"di":1,"l":",","r":"1","o":",.1.,","f":["raw_only"]},
{"fi":71,"di":0,"l":":","r":"0","o":":.0.:","f":["raw_only"]}
]
}
```
### Ultra-compact array variant (if parser knows structure/index = array pos)
```json
{
"base":"base72",
"size":72,
"delimiter_default":".",
"delimiter_escape":"·",
"items":[
["0",":","0.:.0",["raw_only"]],
["1",",","1.,.1",["raw_only"]],
["2",")","2.).2",["raw_only"]],
["3","(","3.(.3",["raw_only"]],
["4","*","4.*.4",["raw_only"]],
["5","!","5.!.5",["raw_only"]],
["6","~","6.~.6",["url"]],
["7",".","7·.·7",["raw_only"]],
["8","_","8._.8",["url"]],
["9","-","9.-.9",["url"]],
["A","z","A.z.A",["dns","url"]],
["B","y","B.y.B",["dns","url"]],
// ... (abbreviating for brevity; continue pattern for 10–61 as before)
["-","9","-.9.-",["url"]],
["_","8","_.8._",["url"]],
[".","7",".·7·.",["raw_only"]],
["~","6","~.6.~",["url"]],
["!","5","!.5.!",["raw_only"]],
["*","4","*.4.*",["raw_only"]],
["(","3","(.3.(",["raw_only"]],
[")","2",") .2.)",["raw_only"]],
[",","1",",.1.,",["raw_only"]],
[":","0",":.0.:",["raw_only"]]
]
}
```
This variant is solid for CI-friendly storage and avoids common pitfalls in URL-safe encoding contexts.
Here’s a clean Python validation script for the Base-72 Safe Separator Variant dyads you shared (the one with digits paired to punctuation symbols like `: , ) ( * ! ~ . _ -` and middle-dot `·` escaping for the dot dyads).
The script does the following:
– Defines the full 72-symbol alphabet in correct order
– Verifies the mirror rule (`alphabet[i] ↔ alphabet[71-i]`)
– Reconstructs / validates every oscillator string (with special handling for dot dyads)
– Checks safe_flags consistency (basic rules)
– Offers simple encoding/decoding round-trip test examples
```python
#!/usr/bin/env python3
"""
Base-72 Safe Separator Variant Validator
- Alphabet: 0-9 A-Z a-z - _ . ~ ! * ( ) , :
- Mirror rule: index i ↔ 71 - i
- Oscillator: L . R . L (except for dot dyads → uses middle dot · U+00B7)
- Validates symmetry, oscillator construction, and basic safety rules
"""
import unicodedata
# ────────────────────────────────────────────────
# Full alphabet (index 0 → 71)
# ────────────────────────────────────────────────
ALPHABET = (
"0123456789" # 0–9
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" # 10–35
"abcdefghijklmnopqrstuvwxyz" # 36–61
"-_.~!*(),:" # 62–71
)
assert len(ALPHABET) == 72, f"Alphabet length is {len(ALPHABET)}, expected 72"
MIDDLE_DOT = "\u00b7" # · (U+00B7)
def get_dual_index(i: int) -> int:
return 71 - i
def get_dual_char(i: int) -> str:
return ALPHABET[get_dual_index(i)]
def build_oscillator(left: str, right: str) -> str:
"""Build L·R·L or L.R.L depending on whether dot is involved"""
if "." in (left, right):
delim = MIDDLE_DOT
else:
delim = "."
return f"{left}{delim}{right}{delim}{left}"
def is_dns_safe(c: str) -> bool:
"""Very basic DNS label char check (a-z A-Z 0-9 -)"""
return c.isalnum() or c == "-"
def is_url_safe_pair(l: str, r: str) -> bool:
"""Heuristic: neither is heavily reserved/ambiguous in URLs"""
dangerous = set(".()*,!:")
return not (l in dangerous or r in dangerous)
# ────────────────────────────────────────────────
# Validation routines
# ────────────────────────────────────────────────
def validate_alphabet_symmetry() -> bool:
print("Checking mirror symmetry...")
ok = True
for i in range(72):
dual_i = get_dual_index(i)
if ALPHABET[i] != get_dual_char(dual_i):
print(f" FAIL symmetry at {i} ↔ {dual_i}: "
f"{ALPHABET[i]} ≠ {ALPHABET[dual_i]}")
ok = False
return ok
def validate_oscillators() -> bool:
print("\nValidating oscillators...")
ok = True
for i in range(72):
left = ALPHABET[i]
right = get_dual_char(i)
expected = build_oscillator(left, right)
# For demo: we could load from your JSON, but here we reconstruct
print(f" {i:2d} | {left} ↔ {right} → {expected}")
# Basic sanity
if left == "." or right == ".":
if MIDDLE_DOT not in expected:
print(f" → Missing middle-dot for dot dyad")
ok = False
elif MIDDLE_DOT in expected:
print(f" → Unexpected middle-dot in non-dot dyad")
ok = False
return ok
def check_safety_rules() -> bool:
print("\nChecking basic safety flag heuristics...")
ok = True
for i in range(72):
l = ALPHABET[i]
r = get_dual_char(i)
dns_ok = is_dns_safe(l) and is_dns_safe(r)
url_ok = is_url_safe_pair(l, r)
if dns_ok:
print(f" {i:2d} {l}↔{r} → should allow 'dns'")
elif url_ok:
print(f" {i:2d} {l}↔{r} → should allow 'url'")
else:
print(f" {i:2d} {l}↔{r} → raw_only")
return ok
def simple_roundtrip_test(count=5):
print(f"\nSimple encode/decode round-trip test (first {count} chars)...")
for i in range(count):
ch = ALPHABET[i]
idx = ALPHABET.index(ch)
dual_idx = get_dual_index(idx)
dual_ch = ALPHABET[dual_idx]
print(f" {ch} (idx {idx:2d}) → dual {dual_ch} (idx {dual_idx:2d})")
def main():
print("Base-72 Safe Separator Variant Validation\n")
print(f"Alphabet: {ALPHABET}")
print(f"Length: {len(ALPHABET)}\n")
all_ok = True
all_ok &= validate_alphabet_symmetry()
all_ok &= validate_oscillators()
all_ok &= check_safety_rules()
simple_roundtrip_test(10)
if all_ok:
print("\nAll structural validations passed ✓")
else:
print("\nSome validations failed ⚠️")
if __name__ == "__main__":
main()
```
### How to use
```bash
# Save as e.g. validate_base72.py
python3 validate_base72.py
```
### What it outputs (summary)
- Symmetry check (should all pass)
- All 72 oscillator strings printed (with `·` only where expected)
- Basic safety flag suggestions per pair
- Quick round-trip examples
### Optional extensions you can add:
- Load your actual JSON file and compare reconstructed oscillators vs stored ones
- Implement full encode/decode functions (map char → index, index → char)
- Add percent-encoding simulation for URL context testing
- Generate test strings like `"A.z.A"` → decode back to `"A"`