ethernium-continuity-lite 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ethernium_continuity_lite-2.1.0/LICENSE +22 -0
- ethernium_continuity_lite-2.1.0/PKG-INFO +92 -0
- ethernium_continuity_lite-2.1.0/README.md +38 -0
- ethernium_continuity_lite-2.1.0/continuity_lite/continuity_legacy/run_continuity_lite.py +247 -0
- ethernium_continuity_lite-2.1.0/continuity_lite/continuity_legacy/sync_translations.py +79 -0
- ethernium_continuity_lite-2.1.0/ethernium_continuity_lite.egg-info/PKG-INFO +92 -0
- ethernium_continuity_lite-2.1.0/ethernium_continuity_lite.egg-info/SOURCES.txt +12 -0
- ethernium_continuity_lite-2.1.0/ethernium_continuity_lite.egg-info/dependency_links.txt +1 -0
- ethernium_continuity_lite-2.1.0/ethernium_continuity_lite.egg-info/entry_points.txt +2 -0
- ethernium_continuity_lite-2.1.0/ethernium_continuity_lite.egg-info/requires.txt +2 -0
- ethernium_continuity_lite-2.1.0/ethernium_continuity_lite.egg-info/top_level.txt +1 -0
- ethernium_continuity_lite-2.1.0/pyproject.toml +34 -0
- ethernium_continuity_lite-2.1.0/setup.cfg +4 -0
- ethernium_continuity_lite-2.1.0/tests/test_lite_logic.py +85 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Ethernium (X: @Steveblackbeard)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ethernium-continuity-lite
|
|
3
|
+
Version: 2.1.0
|
|
4
|
+
Summary: Continuity Legacy (Lite): A professional AI continuity framework for zero-friction context handoffs.
|
|
5
|
+
Author: SteveBlackbeard
|
|
6
|
+
Project-URL: Homepage, https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.8
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: typer[all]>=0.9.0
|
|
14
|
+
Requires-Dist: rich>=13.0.0
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# Continuity Lite (v2.1.0) - Evolution DNA Guardian
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
[](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
|
|
22
|
+
|
|
23
|
+
[](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
|
|
24
|
+
|
|
25
|
+
[](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
**Lite** is the fastest contextual guardian for Human-AI parity. Zero dependencies, instant execution.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## Installation (Quick)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
|
|
43
|
+
# Install the Lite edition from its folder
|
|
44
|
+
|
|
45
|
+
pip install -e .
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Setup the DNA Guardian Entry Point
|
|
50
|
+
|
|
51
|
+
continuity-lite --hook
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## Minimal Usage
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
|
|
67
|
+
# Run the DNA validation cycle
|
|
68
|
+
|
|
69
|
+
continuity-lite
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## Hardware Profile
|
|
80
|
+
|
|
81
|
+
- **CPU**: Minimal (Any).
|
|
82
|
+
|
|
83
|
+
- **RAM**: < 100MB.
|
|
84
|
+
|
|
85
|
+
- **Python**: 3.7+ (No external dependencies).
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
*Continuity: Protecting the logical lineage of your software.*
|
|
92
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Continuity Lite (v2.1.0) - Evolution DNA Guardian
|
|
2
|
+
|
|
3
|
+
[](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
|
|
4
|
+
[](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
|
|
5
|
+
[](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
|
|
6
|
+
|
|
7
|
+
**Lite** is the fastest contextual guardian for Human-AI parity. Zero dependencies, instant execution.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Installation (Quick)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Install the Lite edition from its folder
|
|
15
|
+
pip install -e .
|
|
16
|
+
|
|
17
|
+
# Setup the DNA Guardian Entry Point
|
|
18
|
+
continuity-lite --hook
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Minimal Usage
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Run the DNA validation cycle
|
|
27
|
+
continuity-lite
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Hardware Profile
|
|
33
|
+
- **CPU**: Minimal (Any).
|
|
34
|
+
- **RAM**: < 100MB.
|
|
35
|
+
- **Python**: 3.7+ (No external dependencies).
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
*Continuity: Protecting the logical lineage of your software.*
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import hashlib
|
|
3
|
+
import os
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from typing import Optional
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
import typer
|
|
11
|
+
from rich.console import Console
|
|
12
|
+
from rich.panel import Panel
|
|
13
|
+
from rich.table import Table
|
|
14
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
15
|
+
from rich import print as rprint
|
|
16
|
+
|
|
17
|
+
# CONTINUITY LEGACY Lite (v2.1.0) - Evolution DNA Guardian
|
|
18
|
+
# -------------------------------------------------------------
|
|
19
|
+
# [!] Industrial Grade Refactor: Typer CLI, Rich UI, SHA-256 Signatures, Structured Logs.
|
|
20
|
+
|
|
21
|
+
app = typer.Typer(
|
|
22
|
+
help="🏛️ Continuity Legacy Lite: The professional AI continuity framework.",
|
|
23
|
+
add_completion=False,
|
|
24
|
+
no_args_is_help=True
|
|
25
|
+
)
|
|
26
|
+
console = Console()
|
|
27
|
+
|
|
28
|
+
def setup_logger(repo_root: Path):
|
|
29
|
+
log_dir = repo_root / ".continuity" / "logs"
|
|
30
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
31
|
+
|
|
32
|
+
log_file = log_dir / f"continuity_{datetime.now().strftime('%Y%m%d')}.jsonl"
|
|
33
|
+
|
|
34
|
+
# Custom JSON Formatter
|
|
35
|
+
class JsonFormatter(logging.Formatter):
|
|
36
|
+
def format(self, record):
|
|
37
|
+
log_record = {
|
|
38
|
+
"timestamp": datetime.utcnow().isoformat() + "Z",
|
|
39
|
+
"level": record.levelname,
|
|
40
|
+
"message": record.getMessage(),
|
|
41
|
+
"module": record.module
|
|
42
|
+
}
|
|
43
|
+
if hasattr(record, "dna_hash"):
|
|
44
|
+
log_record["dna_hash"] = record.dna_hash
|
|
45
|
+
return json.dumps(log_record)
|
|
46
|
+
|
|
47
|
+
logger = logging.getLogger("continuity")
|
|
48
|
+
logger.setLevel(logging.INFO)
|
|
49
|
+
|
|
50
|
+
if not logger.handlers:
|
|
51
|
+
fh = logging.FileHandler(log_file)
|
|
52
|
+
fh.setFormatter(JsonFormatter())
|
|
53
|
+
logger.addHandler(fh)
|
|
54
|
+
return logger
|
|
55
|
+
|
|
56
|
+
ASCII_ART = """
|
|
57
|
+
[bold cyan]
|
|
58
|
+
______ ____ _ __ ______ ____ _ __ _ __ ____ ______ __ __
|
|
59
|
+
/ ____// __ \\ / | / //_ __// _// | / // / / //_ __//_ __/ \\ \\/ /
|
|
60
|
+
/ / / / / // |/ / / / / / / |/ // / / / / / / / \\ /
|
|
61
|
+
/ /___ / /_/ // /| / / / _/ / / /| // /__/ / / / / / / /
|
|
62
|
+
\\____/ \\____//_/ |_/ /_/ /___//_/ |_/ \\____/ /_/ /_/ /_/
|
|
63
|
+
|
|
64
|
+
LEGACY [bold white]v2.1.0[/bold white] | [italic green]Industrial Evolution DNA Guardian[/italic green]
|
|
65
|
+
[/bold cyan]
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
def calculate_sha256(path: Path) -> str:
|
|
69
|
+
if not path.exists(): return ""
|
|
70
|
+
return hashlib.sha256(path.read_bytes()).hexdigest()
|
|
71
|
+
|
|
72
|
+
def sign_state(data: dict) -> str:
|
|
73
|
+
"""Generates a SHA-256 signature for the state record.
|
|
74
|
+
Hardware binding has been removed to support Open Source collaboration across
|
|
75
|
+
different developer machines while maintaining semantic integrity.
|
|
76
|
+
"""
|
|
77
|
+
serialized = json.dumps({k: v for k, v in data.items() if k != "signature"}, sort_keys=True)
|
|
78
|
+
return hashlib.sha256(serialized.encode("utf-8")).hexdigest()
|
|
79
|
+
|
|
80
|
+
def ensure_file(path: Path, template: str, description: str):
|
|
81
|
+
if not path.exists():
|
|
82
|
+
console.log(f"[yellow][?][/yellow] Missing Nucleotide: [bold]{description}[/bold]")
|
|
83
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
84
|
+
path.write_text(template, encoding="utf-8")
|
|
85
|
+
console.log(f" [green][✔][/green] Re-synthesized: [italic]{path.name}[/italic]")
|
|
86
|
+
return True
|
|
87
|
+
return False
|
|
88
|
+
|
|
89
|
+
def install_hooks(repo_root: Path):
|
|
90
|
+
hook_path = repo_root / ".git" / "hooks" / "pre-push"
|
|
91
|
+
if not (repo_root / ".git").exists():
|
|
92
|
+
console.log("[bold red][!][/bold red] ERROR: Not a git repository. Cannot install hooks.")
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
# Vector 1: Prevenir secuestro de $PATH inyectando ruta absoluta al binario
|
|
96
|
+
abs_python = sys.executable.replace("\\", "/")
|
|
97
|
+
abs_script = Path(__file__).resolve().as_posix()
|
|
98
|
+
|
|
99
|
+
# Vector 3: Mantener política Fail-Closed (|| exit 1)
|
|
100
|
+
hook_content = f"#!/bin/sh\n# Continuity Sentinel Guardian (Fail-Closed Security)\necho '[*] 🏛️ Ethernium: Guarding DNA Lineage...'\n\"{abs_python}\" \"{abs_script}\" check\nRESULT=$?\nif [ $RESULT -ne 0 ]; then\n echo '[!] PUSH REJECTED: DNA Drift Detected. Run continuity-lite check.'\n exit 1\nfi\nexit 0\n"
|
|
101
|
+
hook_path.parent.mkdir(parents=True, exist_ok=True)
|
|
102
|
+
hook_path.write_text(hook_content, encoding="utf-8")
|
|
103
|
+
|
|
104
|
+
if os.name != "nt": os.chmod(hook_path, 0o755)
|
|
105
|
+
console.log(f"[green][✔][/green] Push Hook Guardian (v2.1.0) installed and active.")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def build_merkle_root(hashes: list[str]) -> str:
|
|
109
|
+
"""RFC 6962 compliant Merkle Tree with leaf/node prefix hardening."""
|
|
110
|
+
if not hashes: return "0" * 64
|
|
111
|
+
# Leaf nodes: H(0x00 || data)
|
|
112
|
+
current_level = [hashlib.sha256(b"\x00" + h.encode("utf-8")).hexdigest() for h in sorted(hashes)]
|
|
113
|
+
while len(current_level) > 1:
|
|
114
|
+
next_level = []
|
|
115
|
+
if len(current_level) % 2 != 0:
|
|
116
|
+
current_level.append(current_level[-1])
|
|
117
|
+
for i in range(0, len(current_level), 2):
|
|
118
|
+
# Internal nodes: H(0x01 || left || right)
|
|
119
|
+
combined = b"\x01" + (current_level[i] + current_level[i+1]).encode("utf-8")
|
|
120
|
+
next_level.append(hashlib.sha256(combined).hexdigest())
|
|
121
|
+
current_level = next_level
|
|
122
|
+
return current_level[0]
|
|
123
|
+
|
|
124
|
+
@app.command()
|
|
125
|
+
def init(
|
|
126
|
+
repo_root: Path = typer.Option(".", "--repo-root", help="Project root directory."),
|
|
127
|
+
no_hook: bool = typer.Option(False, "--no-hook", help="Disable automatic Git-Hook installation.")
|
|
128
|
+
):
|
|
129
|
+
"""Initialize the Continuity memory core in the current project."""
|
|
130
|
+
console.print(ASCII_ART)
|
|
131
|
+
logger = setup_logger(repo_root)
|
|
132
|
+
|
|
133
|
+
root = repo_root.resolve()
|
|
134
|
+
logger.info("Initializing Continuity Core", extra={"repo_root": str(root)})
|
|
135
|
+
|
|
136
|
+
with Progress(
|
|
137
|
+
SpinnerColumn(),
|
|
138
|
+
TextColumn("[progress.description]{task.description}"),
|
|
139
|
+
transient=True,
|
|
140
|
+
) as progress:
|
|
141
|
+
progress.add_task(description="Forging memory core...", total=None)
|
|
142
|
+
|
|
143
|
+
# Create core files
|
|
144
|
+
ensure_file(root / "PROJECT_CONTEXT.md", "# Project Context\n\n- Define your project core here.", "PROJECT_CONTEXT.md")
|
|
145
|
+
ensure_file(root / "LIVE_HANDOFF.md", "# Live Handoff\n\n- No handoff pending.", "LIVE_HANDOFF.md")
|
|
146
|
+
|
|
147
|
+
# Create and SIGN STATE.json
|
|
148
|
+
state_path = root / "STATE.json"
|
|
149
|
+
if not state_path.exists():
|
|
150
|
+
state_data = {"phase": "stable", "last_update": datetime.utcnow().isoformat()}
|
|
151
|
+
state_data["signature"] = sign_state(state_data)
|
|
152
|
+
state_path.write_text(json.dumps(state_data, indent=2), encoding="utf-8")
|
|
153
|
+
console.log(f" [green][✔][/green] Crystallized + Signed: [italic]STATE.json[/italic]")
|
|
154
|
+
|
|
155
|
+
if not no_hook:
|
|
156
|
+
install_hooks(root)
|
|
157
|
+
|
|
158
|
+
console.print(Panel("[bold green]Success:[/bold green] Continuity Core crystallized at root level. 🏛️💎🦾", title="Init Complete", expand=False))
|
|
159
|
+
|
|
160
|
+
@app.command()
|
|
161
|
+
def check(
|
|
162
|
+
repo_root: Path = typer.Option(".", "--repo-root", help="Project root directory.")
|
|
163
|
+
):
|
|
164
|
+
"""Validate the DNA parity, Merkle Root integrity, and state signature."""
|
|
165
|
+
console.print(ASCII_ART)
|
|
166
|
+
root = repo_root.resolve()
|
|
167
|
+
|
|
168
|
+
md_files = []
|
|
169
|
+
for r, dirs, files in os.walk(root):
|
|
170
|
+
dirs[:] = [d for d in dirs if d not in [".git", "node_modules", ".continuity", "outputs"]]
|
|
171
|
+
for f in files:
|
|
172
|
+
if f.endswith(".md") and "PROJECT_DNA" not in f:
|
|
173
|
+
md_files.append(Path(r) / f)
|
|
174
|
+
|
|
175
|
+
nucleotides = [calculate_sha256(md) for md in sorted(md_files)]
|
|
176
|
+
merkle_root = build_merkle_root(nucleotides)
|
|
177
|
+
|
|
178
|
+
# Verify STATE.json signature integrity
|
|
179
|
+
state_path = root / "STATE.json"
|
|
180
|
+
if state_path.exists():
|
|
181
|
+
try:
|
|
182
|
+
state = json.loads(state_path.read_text(encoding="utf-8"))
|
|
183
|
+
# Verify cryptographic signature
|
|
184
|
+
if "signature" in state:
|
|
185
|
+
expected_sig = sign_state(state)
|
|
186
|
+
if state["signature"] != expected_sig:
|
|
187
|
+
console.print(f"[bold red][!] STATE TAMPERING DETECTED:[/bold red] Signature mismatch!")
|
|
188
|
+
console.print(f" Stored: [red]{state['signature'][:16]}...[/red]")
|
|
189
|
+
console.print(f" Expected: [cyan]{expected_sig[:16]}...[/cyan]")
|
|
190
|
+
raise typer.Exit(code=1)
|
|
191
|
+
console.print(f"[green][✔][/green] State signature verified.")
|
|
192
|
+
|
|
193
|
+
# Update Merkle Root in STATE.json
|
|
194
|
+
state["merkle_root"] = merkle_root
|
|
195
|
+
state["last_check"] = datetime.utcnow().isoformat()
|
|
196
|
+
state["signature"] = sign_state(state)
|
|
197
|
+
state_path.write_text(json.dumps(state, indent=2), encoding="utf-8")
|
|
198
|
+
except json.JSONDecodeError:
|
|
199
|
+
console.print("[red][!][/red] Error: Invalid STATE.json nucleotide.")
|
|
200
|
+
|
|
201
|
+
console.print(Panel(f"[bold green]Parity Confirmed:[/bold green] Merkle Root `{merkle_root[:16]}...`", title="DNA Guardian", expand=False))
|
|
202
|
+
|
|
203
|
+
@app.command()
|
|
204
|
+
def status(
|
|
205
|
+
repo_root: Path = typer.Option(".", "--repo-root", help="Project root directory.")
|
|
206
|
+
):
|
|
207
|
+
"""View the current status of the logical lineage."""
|
|
208
|
+
root = repo_root.resolve()
|
|
209
|
+
state_path = root / "STATE.json"
|
|
210
|
+
|
|
211
|
+
if not state_path.exists():
|
|
212
|
+
console.print("[yellow]Continuity not initialized here. Use `init` first.[/yellow]")
|
|
213
|
+
return
|
|
214
|
+
|
|
215
|
+
state = json.loads(state_path.read_text(encoding="utf-8"))
|
|
216
|
+
|
|
217
|
+
table = Table(title="Lineage Status 🏛️", show_header=True, header_style="bold magenta")
|
|
218
|
+
table.add_column("Property", style="dim")
|
|
219
|
+
table.add_column("Value")
|
|
220
|
+
|
|
221
|
+
for k, v in state.items():
|
|
222
|
+
table.add_row(k, str(v))
|
|
223
|
+
|
|
224
|
+
console.print(table)
|
|
225
|
+
|
|
226
|
+
@app.command()
|
|
227
|
+
def log(
|
|
228
|
+
intent: str = typer.Argument(..., help="Detailed session intent capture."),
|
|
229
|
+
repo_root: Path = typer.Option(".", "--repo-root", help="Project root directory.")
|
|
230
|
+
):
|
|
231
|
+
"""Capture session intent into the permanent timeline."""
|
|
232
|
+
root = repo_root.resolve()
|
|
233
|
+
log_path = root / "SESSION_LOG.md"
|
|
234
|
+
|
|
235
|
+
if not log_path.exists():
|
|
236
|
+
log_path.write_text("# Continuity Session Log\n\n", encoding="utf-8")
|
|
237
|
+
|
|
238
|
+
with open(log_path, "a", encoding="utf-8") as f:
|
|
239
|
+
f.write(f"- [{datetime.utcnow().isoformat()}Z] {intent}\n")
|
|
240
|
+
|
|
241
|
+
console.log(f"[green][✔][/green] Intent captured in SESSION_LOG.md")
|
|
242
|
+
|
|
243
|
+
def main():
|
|
244
|
+
app()
|
|
245
|
+
|
|
246
|
+
if __name__ == "__main__":
|
|
247
|
+
main()
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import argparse
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
|
|
10
|
+
# CONTINUITY LEGACY: Active Universal Translation Sync
|
|
11
|
+
# ----------------------------------------------------
|
|
12
|
+
# This script manages multilingual documentation across the 4 levels:
|
|
13
|
+
# Root, Pro, Lite, and Omega. It detects drift and can auto-generate READMEs.
|
|
14
|
+
|
|
15
|
+
LANG_CODES = ["es", "ja", "ru", "zh", "fr", "it", "de", "pt", "en"]
|
|
16
|
+
|
|
17
|
+
def calculate_md5(path: Path) -> str:
|
|
18
|
+
if not path.exists(): return ""
|
|
19
|
+
return hashlib.md5(path.read_bytes()).hexdigest()
|
|
20
|
+
|
|
21
|
+
def get_edition_name(root: Path) -> str:
|
|
22
|
+
# Detect which edition we are in
|
|
23
|
+
if (root / "CONTINUITY LEGACY Pro").exists(): return "Root Portal"
|
|
24
|
+
if "Pro" in root.name: return "Pro Edition"
|
|
25
|
+
if "Lite" in root.name: return "Lite Edition"
|
|
26
|
+
if "Omega" in root.name: return "Omega Edition"
|
|
27
|
+
return "Universal Core"
|
|
28
|
+
|
|
29
|
+
def generate_localized_readme(lang, edition_name, source_content):
|
|
30
|
+
# Professional localized templates
|
|
31
|
+
templates = {
|
|
32
|
+
"es": f"# CONTINUITY LEGACY: {edition_name}\n\nVersión localizada del framework de continuidad técnica.",
|
|
33
|
+
"ja": f"# CONTINUITY LEGACY: {edition_name}\n\nテクニカル・コンティニュイティ・フレームワークのローカライズ版。",
|
|
34
|
+
"ru": f"# CONTINUITY LEGACY: {edition_name}\n\nЛокализованная версия фреймворка технической непрерывности.",
|
|
35
|
+
"zh": f"# CONTINUITY LEGACY: {edition_name}\n\n技术连续性框架的本地化版本。",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Generic fallback
|
|
39
|
+
base = templates.get(lang, f"# CONTINUITY LEGACY: {edition_name}\n\nLocalized version of the technical continuity framework.")
|
|
40
|
+
|
|
41
|
+
# Add strategic metadata footer
|
|
42
|
+
footer = f"\n\n---\n*CONTINUITY LEGACY: Global Infrastructure - Generated {datetime.utcnow().isoformat()}Z*"
|
|
43
|
+
return base + footer
|
|
44
|
+
|
|
45
|
+
def sync_all(repo_root: Path, auto_gen: bool):
|
|
46
|
+
edition = get_edition_name(repo_root)
|
|
47
|
+
source_path = repo_root / "README.md"
|
|
48
|
+
|
|
49
|
+
if not source_path.exists():
|
|
50
|
+
print(f"[!] ERROR: Source README.md not found in {repo_root}")
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
print(f"[*] SYNC: Analyzing {edition} in {repo_root}...")
|
|
54
|
+
source_hash = calculate_md5(source_path)
|
|
55
|
+
|
|
56
|
+
lang_dir = repo_root / "OTHER_LANGUAGES"
|
|
57
|
+
lang_dir.mkdir(parents=True, exist_ok=True)
|
|
58
|
+
|
|
59
|
+
for lang in LANG_CODES:
|
|
60
|
+
target_path = lang_dir / f"README_{lang}.md"
|
|
61
|
+
|
|
62
|
+
if auto_gen:
|
|
63
|
+
print(f" -> Updating {lang} README...")
|
|
64
|
+
content = generate_localized_readme(lang, edition, source_path.read_text(encoding="utf-8"))
|
|
65
|
+
target_path.write_text(content, encoding="utf-8")
|
|
66
|
+
|
|
67
|
+
print(f"[✔] SYNC: {edition} is now globally synchronized.")
|
|
68
|
+
|
|
69
|
+
def main() -> None:
|
|
70
|
+
parser = argparse.ArgumentParser(description="Active Universal Translation Sync.")
|
|
71
|
+
parser.add_argument("--repo-root", default=".")
|
|
72
|
+
parser.add_argument("--auto-generate", action="store_true", help="Automatically generate/update localized files.")
|
|
73
|
+
args = parser.parse_args()
|
|
74
|
+
|
|
75
|
+
root = Path(args.repo_root).resolve()
|
|
76
|
+
sync_all(root, args.auto_generate)
|
|
77
|
+
|
|
78
|
+
if __name__ == "__main__":
|
|
79
|
+
main()
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ethernium-continuity-lite
|
|
3
|
+
Version: 2.1.0
|
|
4
|
+
Summary: Continuity Legacy (Lite): A professional AI continuity framework for zero-friction context handoffs.
|
|
5
|
+
Author: SteveBlackbeard
|
|
6
|
+
Project-URL: Homepage, https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.8
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: typer[all]>=0.9.0
|
|
14
|
+
Requires-Dist: rich>=13.0.0
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# Continuity Lite (v2.1.0) - Evolution DNA Guardian
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
[](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
|
|
22
|
+
|
|
23
|
+
[](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
|
|
24
|
+
|
|
25
|
+
[](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
**Lite** is the fastest contextual guardian for Human-AI parity. Zero dependencies, instant execution.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## Installation (Quick)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
|
|
43
|
+
# Install the Lite edition from its folder
|
|
44
|
+
|
|
45
|
+
pip install -e .
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Setup the DNA Guardian Entry Point
|
|
50
|
+
|
|
51
|
+
continuity-lite --hook
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## Minimal Usage
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
|
|
67
|
+
# Run the DNA validation cycle
|
|
68
|
+
|
|
69
|
+
continuity-lite
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## Hardware Profile
|
|
80
|
+
|
|
81
|
+
- **CPU**: Minimal (Any).
|
|
82
|
+
|
|
83
|
+
- **RAM**: < 100MB.
|
|
84
|
+
|
|
85
|
+
- **Python**: 3.7+ (No external dependencies).
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
*Continuity: Protecting the logical lineage of your software.*
|
|
92
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
continuity_lite/continuity_legacy/run_continuity_lite.py
|
|
5
|
+
continuity_lite/continuity_legacy/sync_translations.py
|
|
6
|
+
ethernium_continuity_lite.egg-info/PKG-INFO
|
|
7
|
+
ethernium_continuity_lite.egg-info/SOURCES.txt
|
|
8
|
+
ethernium_continuity_lite.egg-info/dependency_links.txt
|
|
9
|
+
ethernium_continuity_lite.egg-info/entry_points.txt
|
|
10
|
+
ethernium_continuity_lite.egg-info/requires.txt
|
|
11
|
+
ethernium_continuity_lite.egg-info/top_level.txt
|
|
12
|
+
tests/test_lite_logic.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
continuity_lite
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ethernium-continuity-lite"
|
|
7
|
+
version = "2.1.0"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "SteveBlackbeard" },
|
|
10
|
+
]
|
|
11
|
+
description = "Continuity Legacy (Lite): A professional AI continuity framework for zero-friction context handoffs."
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.8"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"typer[all]>=0.9.0",
|
|
21
|
+
"rich>=13.0.0",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
"Homepage" = "https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium"
|
|
26
|
+
|
|
27
|
+
[project.scripts]
|
|
28
|
+
continuity-lite = "continuity_lite.continuity_legacy.run_continuity_lite:main"
|
|
29
|
+
|
|
30
|
+
[tool.setuptools.packages.find]
|
|
31
|
+
where = ["."]
|
|
32
|
+
include = ["continuity_lite*"]
|
|
33
|
+
|
|
34
|
+
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import pytest
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
# CONTINUITY LEGACY: Logic Audit Tests (v2.1.1 - RFC 6962 Hardened)
|
|
7
|
+
# ------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
sys.path.append(str(Path(__file__).parent.parent / 'continuity_lite' / 'continuity_legacy'))
|
|
10
|
+
|
|
11
|
+
from run_continuity_lite import build_merkle_root, calculate_sha256, sign_state
|
|
12
|
+
|
|
13
|
+
# --- SHA-256 Tests ---
|
|
14
|
+
|
|
15
|
+
def test_calculate_sha256(tmp_path):
|
|
16
|
+
test_file = tmp_path / "test.txt"
|
|
17
|
+
content = b"Ethernium Continuity Legacy"
|
|
18
|
+
test_file.write_bytes(content)
|
|
19
|
+
expected = hashlib.sha256(content).hexdigest()
|
|
20
|
+
assert calculate_sha256(test_file) == expected
|
|
21
|
+
|
|
22
|
+
def test_calculate_sha256_missing():
|
|
23
|
+
assert calculate_sha256(Path("non_existent_phantom.txt")) == ""
|
|
24
|
+
|
|
25
|
+
# --- Merkle Tree Tests (RFC 6962 compliant) ---
|
|
26
|
+
|
|
27
|
+
def test_build_merkle_root_empty():
|
|
28
|
+
assert build_merkle_root([]) == "0" * 64
|
|
29
|
+
|
|
30
|
+
def test_build_merkle_root_single():
|
|
31
|
+
h1 = "abc123"
|
|
32
|
+
# Single node: leaf hash = H(0x00 || "abc123")
|
|
33
|
+
expected = hashlib.sha256(b"\x00" + b"abc123").hexdigest()
|
|
34
|
+
assert build_merkle_root([h1]) == expected
|
|
35
|
+
|
|
36
|
+
def test_build_merkle_root_even():
|
|
37
|
+
# 2 nodes: sorted ["a", "b"]
|
|
38
|
+
# Leaf: L0 = H(0x00 || "a"), L1 = H(0x00 || "b")
|
|
39
|
+
# Root: H(0x01 || L0 || L1)
|
|
40
|
+
L0 = hashlib.sha256(b"\x00a").hexdigest()
|
|
41
|
+
L1 = hashlib.sha256(b"\x00b").hexdigest()
|
|
42
|
+
expected = hashlib.sha256(b"\x01" + (L0 + L1).encode("utf-8")).hexdigest()
|
|
43
|
+
assert build_merkle_root(["b", "a"]) == expected
|
|
44
|
+
|
|
45
|
+
def test_build_merkle_root_odd():
|
|
46
|
+
# 3 nodes sorted: ["a", "b", "c"]
|
|
47
|
+
# Leaves: L0=H(0x00||"a"), L1=H(0x00||"b"), L2=H(0x00||"c")
|
|
48
|
+
# Padded: L3 = L2 (duplicate)
|
|
49
|
+
# Level 1: N0=H(0x01||L0||L1), N1=H(0x01||L2||L3)
|
|
50
|
+
# Root: H(0x01||N0||N1)
|
|
51
|
+
L0 = hashlib.sha256(b"\x00a").hexdigest()
|
|
52
|
+
L1 = hashlib.sha256(b"\x00b").hexdigest()
|
|
53
|
+
L2 = hashlib.sha256(b"\x00c").hexdigest()
|
|
54
|
+
N0 = hashlib.sha256(b"\x01" + (L0 + L1).encode("utf-8")).hexdigest()
|
|
55
|
+
N1 = hashlib.sha256(b"\x01" + (L2 + L2).encode("utf-8")).hexdigest()
|
|
56
|
+
expected = hashlib.sha256(b"\x01" + (N0 + N1).encode("utf-8")).hexdigest()
|
|
57
|
+
assert build_merkle_root(["c", "b", "a"]) == expected
|
|
58
|
+
|
|
59
|
+
def test_merkle_deterministic_order():
|
|
60
|
+
"""Tree must be order-independent (sorted internally)."""
|
|
61
|
+
assert build_merkle_root(["z", "a", "m"]) == build_merkle_root(["a", "m", "z"])
|
|
62
|
+
|
|
63
|
+
# --- State Signature Tests (Expert #1: Cybersecurity) ---
|
|
64
|
+
|
|
65
|
+
def test_sign_state_deterministic():
|
|
66
|
+
data = {"phase": "stable", "last_update": "2026-01-01T00:00:00"}
|
|
67
|
+
sig1 = sign_state(data)
|
|
68
|
+
sig2 = sign_state(data)
|
|
69
|
+
assert sig1 == sig2
|
|
70
|
+
assert len(sig1) == 64 # SHA-256 hex digest
|
|
71
|
+
|
|
72
|
+
def test_sign_state_excludes_signature_field():
|
|
73
|
+
data = {"phase": "stable", "signature": "old_sig"}
|
|
74
|
+
sig = sign_state(data)
|
|
75
|
+
# Changing the signature field should NOT change the hash
|
|
76
|
+
data2 = {"phase": "stable", "signature": "different_sig"}
|
|
77
|
+
assert sign_state(data2) == sig
|
|
78
|
+
|
|
79
|
+
def test_sign_state_detects_tampering():
|
|
80
|
+
data = {"phase": "stable", "last_update": "2026-01-01T00:00:00"}
|
|
81
|
+
sig = sign_state(data)
|
|
82
|
+
data["phase"] = "compromised"
|
|
83
|
+
assert sign_state(data) != sig
|
|
84
|
+
|
|
85
|
+
|