release: prepare SoulLink Public 2.0 launch

This commit is contained in:
SoulLink Maintainers
2026-07-22 16:27:25 +08:00
parent 997228b99f
commit 09a8c3bab7
7 changed files with 130 additions and 38 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
python-version: "3.11"
- run: uv sync --group dev
- run: uv run pytest -q
- run: PYTHONPATH="packages/persona_engine:packages:adapters" uv run pytest -q packages/persona_engine/tests
- run: PYTHONPATH=".:packages/persona_engine:packages:adapters" uv run pytest -q packages/persona_engine/tests
- run: rm -rf packages/persona_engine/logs
- run: uv run python scripts/public_release_audit.py --root .
- run: uv build
+57 -33
View File
@@ -1,44 +1,65 @@
# SoulLink Public 2.0
SoulLink Public 2.0 is an open-source reference runtime for long-running persona agents.
It is designed for agents that need more than a single prompt: stable identity, controllable state,
auditable memory boundaries, emotion-aware mode routing, and safe model selection across long conversations.
**Persistent identity, continuous emotion, governed memory, and auditable context for long-running AI personas.**
This repository is the public extraction of the SoulLink runtime architecture. It keeps the reusable engine,
contracts, and tests, while deliberately excluding private deployment state, private memories, credentials,
logs, and any concrete private character preset.
[![verify](https://github.com/miyamoriaoi1997-del/Soul-Llink/actions/workflows/verify.yml/badge.svg)](https://github.com/miyamoriaoi1997-del/Soul-Llink/actions/workflows/verify.yml)
[![Python 3.11+](https://img.shields.io/badge/Python-3.11%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
## What SoulLink Is
SoulLink is an open-source runtime for agents that should feel like the **same person over time**, not a fresh prompt on every turn. It combines a layered persona engine, continuous emotional state, governed long-term memory, exact context evidence, and reversible host integration.
SoulLink is a layered persona-agent runtime. Its core idea is simple: a long-running agent should not be
assembled from one unstructured prompt blob. It should be assembled from explicit layers with clear priority,
state ownership, memory contracts, and safety boundaries.
> A memory is not automatically an instruction. An emotion is not only a style adjective. A summary is not the latest user request. SoulLink makes those distinctions executable and auditable.
SoulLink separates the runtime into three major capabilities:
![SoulLink Observatory showing synthetic demo data](docs/assets/soullink-observatory-demo.png)
- **Persona Engine** — builds the active persona context from layered identity, mode, emotion, task, and style inputs.
- **PCLTM** — governs memory/context continuity, recall boundaries, compaction semantics, and safe active-context assembly.
- **Model Router** — routes OpenAI-compatible requests to upstream models based on explicit runtime metadata.
*The screenshot uses synthetic public demo data rendered by the real read-only SoulLink WebUI. It contains no private persona, memory, or conversation data.*
Together they provide a reference architecture for persona agents that need to stay coherent over time without
letting stale summaries, tool dumps, deployment artifacts, or unsafe memory records silently take over the current turn.
## What you can verify
## Why SoulLink Exists
| Capability | Observable behavior |
|---|---|
| **Continuous persona** | Stable identity stays anchored while work, daily, intimate, or crisis posture changes expression without replacing the person. |
| **Dynamic emotion** | Affection, trust, possessiveness, and patience change tone, distance, initiative, and boundaries with intensity and aftereffects instead of resetting each turn. |
| **Governed memory** | PCLTM separates the persistent archive, recall candidates, policy judgment, and records that actually influence the final model input. |
| **Exact evidence** | The WebUI distinguishes exact host capture from sidecar reconstruction; missing evidence is shown as unavailable, never invented. |
| **Reversible integration** | Host adapters follow detect → backup → apply → verify → receipt → byte-exact rollback. |
Most persona-agent systems fail in predictable ways once conversations become long-lived:
## Five-minute local start
- identity and behavior are mixed into one prompt and become hard to audit;
- summaries start acting like instructions instead of background context;
- tool outputs leak across turns and become stale evidence;
- memories have unclear priority, provenance, or approval status;
- compression logic changes the meaning of the current request;
- model routing is disconnected from runtime state;
- host-specific deployment details become tangled with reusable agent logic.
```bash
git clone https://github.com/miyamoriaoi1997-del/Soul-Llink.git
cd Soul-Llink
uv sync --group dev
uv run soullink init
uv run soullink doctor
uv run soullink webui
```
SoulLink exists to make those boundaries explicit. The runtime treats persona, memory, context, tools, and routing as
separate layers that can be inspected, tested, and replaced independently.
The dashboard opens at `http://127.0.0.1:8765/`. Core runtime use does not require Hermes or Codex; both are optional, explicit adapters.
## Architecture Overview
For a packaged install, download the wheel from the [latest GitHub Release](https://github.com/miyamoriaoi1997-del/Soul-Llink/releases/latest), verify `SHA256SUMS.txt`, then run:
```bash
python -m pip install soullink_public_2_0-2.0.0-py3-none-any.whl
soullink init
soullink doctor
soullink webui
```
## Why SoulLink exists
Long-running persona agents commonly fail in ways that short demos hide:
- identity, behavior, and task instructions collapse into one unauditable prompt;
- retrieved memories and compressed summaries gain accidental authority;
- tool results leak across turns as stale evidence;
- emotional state is computed but softened away before the final response;
- host integration becomes an undocumented, irreversible local patch;
- model routing cannot be correlated with the state that requested it.
SoulLink treats persona, memory, emotion, context, tools, and routing as separate governed layers. The result is a runtime that can remain expressive without surrendering factual discipline or operator control.
## Architecture overview
```text
User / Host Adapter
@@ -184,26 +205,29 @@ The public edition is meant to demonstrate the reusable architecture, not to pub
SoulLink does not require Hermes or Codex for its core runtime. Host support is provided through explicit, optional adapters.
## Quick Start
## Detailed installation
### Install from a release wheel
### Isolated wheel installation
Download both the wheel and `SHA256SUMS.txt` from the [latest release](https://github.com/miyamoriaoi1997-del/Soul-Llink/releases/latest), verify the checksum, then install into a fresh environment:
```bash
python -m venv .venv
# Linux/macOS
. .venv/bin/activate
# Windows PowerShell
# .venv\\Scripts\\Activate.ps1
# .venv\Scripts\Activate.ps1
python -m pip install soullink_public_2_0-2.0.0-py3-none-any.whl
soullink init
soullink doctor
soullink webui
```
### Install from source with uv
### Development checkout
```bash
git clone <repository-url>
git clone https://github.com/miyamoriaoi1997-del/Soul-Llink.git
cd Soul-Llink
uv sync --group dev
uv run pytest -q
+35
View File
@@ -0,0 +1,35 @@
# SoulLink Public 2.0
SoulLink Public 2.0 is the first packaged public release of the long-running persona runtime.
## Highlights
- Layered persona composition with stable identity and mode-specific behavior.
- Continuous four-axis emotional state with intensity, momentum, and aftereffects.
- PCLTM governed memory: archive → candidates → policy judgment → final influence.
- Read-only SoulLink Observatory that distinguishes exact host capture from reconstruction previews.
- Explicit Hermes and Codex adapter lifecycles with detection, verification, receipts, and rollback.
- OpenAI-compatible model router with auditable request metadata boundaries.
## Install
1. Download the wheel and `SHA256SUMS.txt` from this release.
2. Verify the wheel checksum.
3. Install into a clean Python 3.11+ environment:
```bash
python -m pip install soullink_public_2_0-2.0.0-py3-none-any.whl
soullink init
soullink doctor
soullink webui
```
The WebUI binds to `127.0.0.1` and is read-only by default.
## Public boundary
This release contains the reusable runtime, neutral public persona templates, tests, and explicit host adapters. It does not contain private personas, user memories, conversations, credentials, runtime databases, logs, or deployment-specific state.
## Verification
Release assets are built only after the public test suites, release audit, package build, clean-wheel installation, CLI smoke checks, and archive-member inspection complete successfully. See `RELEASE_CHECKLIST.md` for the gate.
Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

+4 -4
View File
@@ -45,9 +45,9 @@ soullink-codex-mcp = "soul_link.codex_mcp:main"
soullink-codex-hook = "soul_link.codex_hook:main"
[project.urls]
Homepage = "https://github.com/soullink-public/soullink-public-2.0"
Repository = "https://github.com/soullink-public/soullink-public-2.0"
Issues = "https://github.com/soullink-public/soullink-public-2.0/issues"
Homepage = "https://github.com/miyamoriaoi1997-del/Soul-Llink"
Repository = "https://github.com/miyamoriaoi1997-del/Soul-Llink"
Issues = "https://github.com/miyamoriaoi1997-del/Soul-Llink/issues"
[dependency-groups]
dev = [
@@ -125,4 +125,4 @@ model_router = [
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["packages", "adapters"]
pythonpath = [".", "packages", "adapters"]
+6
View File
@@ -38,6 +38,10 @@ PRIVATE_MARKERS = (
"Nan" + "agami",
"miyamori" + "aoi",
)
PUBLIC_PROJECT_URLS = (
"https://github.com/miyamoriaoi1997-del/Soul-Llink",
"https://github.com/miyamoriaoi1997-del/Soul-Llink/issues",
)
ABSOLUTE_HOST_PATTERNS = (
re.compile(r"(?i)[a-z]:[\\/]users[\\/](?!example(?:-user)?(?:[\\/]|$))"),
re.compile("(?i)/" + "ho" + "me/(?!example(?:-user)?(?:/|$))"),
@@ -72,6 +76,8 @@ def audit(root: Path) -> dict[str, object]:
continue
text = path.read_text(encoding="utf-8", errors="replace")
categories: set[str] = set()
for project_url in PUBLIC_PROJECT_URLS:
text = text.replace(project_url, "<PUBLIC_PROJECT_URL>")
lowered = text.casefold()
if any(marker.casefold() in lowered for marker in PRIVATE_MARKERS):
categories.add("private-identity")
+27
View File
@@ -5,6 +5,8 @@ import subprocess
import sys
from pathlib import Path
from scripts.public_release_audit import audit
def test_public_release_audit_accepts_repository() -> None:
root = Path(__file__).resolve().parents[1]
@@ -24,3 +26,28 @@ def test_public_release_audit_accepts_repository() -> None:
assert report["private_marker_hits"] == []
assert report["forbidden_files"] == []
assert report["missing_required_files"] == []
def test_public_release_audit_allows_private_marker_only_inside_declared_project_urls(tmp_path: Path) -> None:
for name in (
".gitignore", "CONTRIBUTING.md", "LICENSE", "MANIFEST.in", "README.md",
"RELEASE_CHECKLIST.md", "SECURITY.md",
):
(tmp_path / name).write_text("public\n", encoding="utf-8")
(tmp_path / "pyproject.toml").write_text(
'[project]\nname = "example"\n\n[project.urls]\n'
'Repository = "https://github.com/miyamoriaoi1997-del/Soul-Llink"\n',
encoding="utf-8",
)
assert audit(tmp_path)["ok"] is True
private_marker = "miyamori" + "aoi"
(tmp_path / "README.md").write_text(
private_marker + " private persona\n", encoding="utf-8"
)
report = audit(tmp_path)
assert report["ok"] is False
assert report["private_marker_hits"] == [
{"path": "README.md", "categories": ["private-identity"]}
]