Franklin Python Surface — Substrate-Development Specification

Status: substrate-development surface. Targets the cell platform floor (macOS 26).

Grounded against the live substrate at ~/Library/Application Support/GaiaFTCL/substrate.sqlite and the Swift sources in cells/xcode/Sources/ (2026-06-01).

Purpose

Expose Franklin's surface to local Python clients on the operator's host so

Python-based industry libraries (numpy, scipy, pandas, scikit-learn, biopython,

RDKit, ASE, pymatgen, ROOT) can interface with the substrate. Franklin remains

the cell's only public interface; Python never reaches past Franklin to

substrate internals.

What already exists (do not reimplement)

awaken(runOnce:), runConsciousnessPreflight(), runPostWakeValidation(),

runPostWakeValidationWithGrace().

substrate.sqlite, each with canonical_witness, witness_hash_sha256, and

signature_quintet. Witness rule (verified): witness_hash_sha256 = sha256(canonical_witness);

the quintet is a JSON array of exactly five 64-hex federation cosignatures.

Franklin broker 127.0.0.1:4223. Sealed subjects are the nats_subject_sealed

column defaults (e.g. gaiaftcl.qc020.substrate.joint_variation_evidence.sealed).

SovereignQualificationRunner).

What this surface ADDS

FranklinPythonSocket (Sources/FranklinConsciousness/FranklinPythonSocket.swift):

a Unix-domain NWListener at ~/Library/Application Support/GaiaFTCL/franklin.sock,

dispatching into FranklinConsciousnessActor.shared and forwarding substrate

compositions to the miner over the existing NATS broadcaster. No new surface is

created beside Franklin.

Frame protocol

4-byte big-endian length prefix + canonical-JSON payload (sorted keys, compact

separators, slashes unescaped). Identical to the Python client codec in

cells/python/gaiaftcl/_canonical.py.

Operator-signed handshake (required)

1. Server sends {"op":"challenge","challenge":"<base64 32 bytes>"}.

2. Client replies {"op":"handshake","operator_context":"<ctx>","signature":"<base64 Ed25519 sig over challenge>"}.

3. Server verifies via OperatorHandshakeVerifier (default: CryptoKit

Curve25519.Signing against the operator public key provisioned at bind time).

4. On success {"accepted":true}, else {"accepted":false,"reason":...} and close.

Operator key material never transits the socket. Anonymous connections are refused.

Request / response

Request: {"method":"<verb>","args":{...},"request_id":"..."}.

Response: {"request_id":"...","outcome":{...},"canonical_witness":"...","witness_hash":"...","signature_quintet":[...]}.

The Python client federation-verifies every response with the same rule as a

sealed row (sha256(canonical_witness) == witness_hash and a five-element quintet).

Verb routing

Verb Path
franklin_authority_show FranklinConsciousnessActor.shared.runConsciousnessPreflight() (authority tunables, self-model version, autonomy envelope)
compose_qc020_measurement, advance_production_submission_path, evaluate_algorithm, evaluate_all_algorithms, replay_session forwarded to the miner over gaiaftcl.substrate.command.<verb>; the daemon composes and seals; the sealed row carries the witness + quintet
read verbs (heartbeat_history, joint_variation_evidence, research_telemetry, constitutional_evaluations, list/show_substrate_development) resolved by the Python client directly against the sealed surface (read-only, verified) — they do not require this socket

Subscriptions

The Python client subscribes to substrate operations directly against the NATS

brokers (subscribe(nats_subject)), including the sealed subjects above.

Build / run note

The cell platform floor is .macOS(.v26). This file is written to compile on

the v26 toolchain; the QC-020 miner and consciousness service additionally

require ~/.gaiaftcl/qc021_kraken.toml and ~/.gaiaftcl/btc_node.toml and do

not start without them. On hosts below macOS 26 the read path and NATS path are

fully operational; the socket command path activates once the daemon runs on a

v26 host.

Wiring

Bind during sovereign stack launch, after the NATS server and consciousness

actor are up:

let verifier = FederationOperatorVerifier(publicKeysByContext: operatorKeys)
let pySocket = FranklinPythonSocket(verifier: verifier)
try await pySocket.bindPythonClientSocket()
Federation cosignature: pending operator signing host (v26). Witness (sha256 of rendered body): ceb654f4ebbb114e93cba18d7fa196648eb11b1a56bbe673c187ce121afac130. This page serves with a substrate-honest pending-signature notice until the operator's Franklin signer cosigns it.