Skip to content

Commit 8f0f77f

Browse files
author
Neo
committed
feat: clean gateway startup, communication channels setup, remove branding refs
- Gateway foreground mode now shows clean banner + ready indicator instead of dumping verbose internal logs to terminal. Logs go to data/gateway.log. Errors/warnings still surface. --verbose flag available for developers. - Setup wizard adds step 7: communication channels (Telegram, Discord, email, webhooks) so users configure notifications during first boot. - Removed third-party branding from user-facing text and docs.
1 parent 97d8c2a commit 8f0f77f

7 files changed

Lines changed: 151 additions & 20 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ All notable changes to 0pnMatrx are documented here.
222222
- Audit gate on deploy: critical vulnerabilities block deployment
223223
- Audit report included in every contract conversion response
224224
- Morpheus enforces audit findings — no unsafe contracts reach the chain
225-
- Claude Mythos Preview added as model provider (Glasswing frontier model)
225+
- Mythos Preview added as model provider (Glasswing frontier model)
226226
- Security configuration in openmatrix.config.json
227227
- HiveMind security instance type for collective vulnerability reasoning
228228
- Ultron deploy planning now includes mandatory security audit step

cli/gateway.py

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,25 +131,77 @@ def cmd_start(args) -> None:
131131
_info(f"Check status: {CYAN}openmatrix gateway status{NC}")
132132
print()
133133
else:
134-
# Foreground mode
134+
# Foreground mode — clean output, logs go to file
135+
LOG_FILE.parent.mkdir(parents=True, exist_ok=True)
136+
log_fd = open(LOG_FILE, "a")
137+
138+
env = os.environ.copy()
139+
if not args.verbose:
140+
env["OPNMATRX_LOG_LEVEL"] = "WARNING"
141+
142+
proc = subprocess.Popen(
143+
[python, "-m", "gateway.server"],
144+
cwd=str(PROJECT_ROOT),
145+
stdout=log_fd,
146+
stderr=subprocess.PIPE,
147+
env=env,
148+
)
149+
_write_pid(proc.pid)
150+
151+
# Wait briefly to confirm it started
152+
time.sleep(1.5)
153+
if proc.poll() is not None:
154+
stderr_out = proc.stderr.read().decode() if proc.stderr else ""
155+
log_fd.close()
156+
_error("Gateway failed to start.")
157+
if stderr_out.strip():
158+
print(stderr_out.strip(), file=sys.stderr)
159+
_info(f"Check logs: {CYAN}openmatrix gateway logs{NC}")
160+
_remove_pid()
161+
sys.exit(1)
162+
135163
print()
136164
print(f" {CYAN}{BOLD}┌──────────────────────────────────┐{NC}")
137165
print(f" {CYAN}{BOLD}│ 0pnMatrx Gateway — Live │{NC}")
138166
print(f" {CYAN}{BOLD}└──────────────────────────────────┘{NC}")
139167
print()
140168
_info(f"Listening on {BOLD}http://{host}:{port}{NC}")
169+
print(f" {GREEN}{NC} Gateway ready")
170+
print()
171+
_info(f"Logs: {DIM}{LOG_FILE}{NC}")
141172
_info("Press Ctrl+C to stop")
142173
print()
143174

144175
try:
145-
proc = subprocess.run(
146-
[python, "-m", "gateway.server"],
147-
cwd=str(PROJECT_ROOT),
148-
)
149-
sys.exit(proc.returncode)
176+
# Monitor subprocess — forward only errors to terminal
177+
while proc.poll() is None:
178+
if proc.stderr:
179+
line = proc.stderr.readline()
180+
if line:
181+
decoded = line.decode().strip()
182+
log_fd.write(decoded + "\n")
183+
log_fd.flush()
184+
# Show warnings/errors to user
185+
if any(k in decoded.upper() for k in ("ERROR", "CRITICAL", "FATAL")):
186+
_error(decoded)
187+
elif "WARNING" in decoded.upper():
188+
_warn(decoded)
189+
else:
190+
time.sleep(0.5)
150191
except KeyboardInterrupt:
151192
print()
193+
_info("Stopping gateway...")
194+
proc.terminate()
195+
try:
196+
proc.wait(timeout=10)
197+
except subprocess.TimeoutExpired:
198+
proc.kill()
152199
_info("Gateway stopped.")
200+
finally:
201+
_remove_pid()
202+
log_fd.close()
203+
if proc.poll() is not None and proc.returncode and proc.returncode != 0:
204+
sys.exit(proc.returncode)
153205

154206

155207
def cmd_stop(args) -> None:
@@ -281,6 +333,10 @@ def register_gateway_commands(subparsers) -> None:
281333
"-p", "--port", type=int, default=None,
282334
help="Override gateway port",
283335
)
336+
start.add_argument(
337+
"-v", "--verbose", action="store_true",
338+
help="Show full server logs in the terminal",
339+
)
284340
start.set_defaults(func=cmd_start)
285341

286342
# stop

docs/FINETUNING_GUIDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ data/finetuning/
9898
## Submitting to the Fine-Tuning API
9999

100100
Follow the Anthropic fine-tuning documentation:
101-
https://docs.anthropic.com/en/docs/build-with-claude/fine-tuning
101+
https://docs.anthropic.com/en/docs/build-with-anthropic/fine-tuning
102102

103103
---
104104

runtime/models/anthropic_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44
Anthropic model provider for 0pnMatrx.
55
6-
Supports Claude models via the Messages API.
6+
Supports Anthropic models via the Messages API.
77
API key loaded from config — never hardcoded.
88
"""
99

runtime/models/mythos_client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"""
2-
Claude Mythos Preview — Glasswing cybersecurity-focused frontier model.
2+
Mythos Preview — Glasswing cybersecurity-focused frontier model.
33
4-
Uses the Anthropic API but targets Claude Mythos Preview specifically.
4+
Uses the Anthropic API but targets Mythos Preview specifically.
55
Glasswing models are optimised for vulnerability detection, code security
66
analysis, and exploit identification.
77
8-
Access: Claude API, Amazon Bedrock, Google Vertex AI, Microsoft Foundry.
8+
Access: Anthropic API, Amazon Bedrock, Google Vertex AI, Microsoft Foundry.
99
"""
1010

1111
from __future__ import annotations
@@ -23,7 +23,7 @@ class MythosClient(AnthropicClient):
2323
"""Anthropic Mythos model provider — security-optimised frontier model.
2424
2525
Inherits all Anthropic API logic. Overrides the model name to target
26-
Claude Mythos Preview for security-critical operations.
26+
Mythos Preview for security-critical operations.
2727
"""
2828

2929
def __init__(self, config: dict) -> None:

scripts/prepare_finetuning.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def main() -> None:
141141

142142
print(f"\nNext steps:")
143143
print(f" 1. Review exported files in {output_dir}/")
144-
print(f" 2. Submit via Anthropic fine-tuning API: https://docs.anthropic.com/en/docs/build-with-claude/fine-tuning")
144+
print(f" 2. Submit via Anthropic fine-tuning API: https://docs.anthropic.com/en/docs/build-with-anthropic/fine-tuning")
145145
print(f" 3. Evaluate fine-tuned model against base model on held-out validation set")
146146

147147

setup.py

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def configure_model(config):
174174
{BOLD}Which AI model provider do you want to use?{RESET}
175175
176176
{CYAN}1{RESET} Ollama {DIM}(free, local, private — recommended for getting started){RESET}
177-
{CYAN}2{RESET} Anthropic {DIM}(Claude models — best quality){RESET}
177+
{CYAN}2{RESET} Anthropic {DIM}(best quality){RESET}
178178
{CYAN}3{RESET} OpenAI {DIM}(GPT models){RESET}
179179
{CYAN}4{RESET} NVIDIA {DIM}(NVIDIA AI endpoints){RESET}
180180
{CYAN}5{RESET} Google {DIM}(Gemini models){RESET}
@@ -339,6 +339,77 @@ def configure_security(config):
339339
success("Blocking on CRITICAL findings only")
340340

341341

342+
def configure_communications(config):
343+
"""Set up notification and communication channels."""
344+
print(f"""
345+
{BOLD}How should 0pnMatrx reach you?{RESET}
346+
{DIM}Select your preferred notification channels.{RESET}
347+
{DIM}You can configure multiple channels.{RESET}
348+
""")
349+
350+
channels = {}
351+
352+
# Telegram
353+
use_telegram = ask("Enable Telegram notifications?", default="no", options=["yes", "no"])
354+
if use_telegram.lower() == "yes":
355+
bot_token = ask("Telegram Bot Token (from @BotFather)")
356+
chat_id = ask("Telegram Chat ID")
357+
if bot_token and chat_id:
358+
channels["telegram"] = {
359+
"enabled": True,
360+
"bot_token": bot_token,
361+
"chat_id": chat_id,
362+
}
363+
success("Telegram configured")
364+
365+
# Discord
366+
use_discord = ask("Enable Discord notifications?", default="no", options=["yes", "no"])
367+
if use_discord.lower() == "yes":
368+
webhook_url = ask("Discord Webhook URL")
369+
if webhook_url:
370+
channels["discord"] = {
371+
"enabled": True,
372+
"webhook_url": webhook_url,
373+
}
374+
success("Discord configured")
375+
376+
# Email
377+
use_email = ask("Enable email notifications?", default="no", options=["yes", "no"])
378+
if use_email.lower() == "yes":
379+
smtp_host = ask("SMTP host", default="smtp.gmail.com")
380+
smtp_port = ask("SMTP port", default="587")
381+
smtp_user = ask("SMTP username (email address)")
382+
smtp_pass = ask("SMTP password or app password")
383+
to_addr = ask("Send notifications to (email)", default=smtp_user)
384+
if smtp_user:
385+
channels["email"] = {
386+
"enabled": True,
387+
"smtp_host": smtp_host,
388+
"smtp_port": int(smtp_port),
389+
"smtp_user": smtp_user,
390+
"smtp_pass": smtp_pass,
391+
"to": to_addr,
392+
}
393+
success("Email configured")
394+
395+
# Webhooks
396+
use_webhook = ask("Enable custom webhook notifications?", default="no", options=["yes", "no"])
397+
if use_webhook.lower() == "yes":
398+
url = ask("Webhook URL (POST)")
399+
if url:
400+
channels["webhook"] = {
401+
"enabled": True,
402+
"url": url,
403+
}
404+
success("Webhook configured")
405+
406+
if not channels:
407+
info("No notification channels configured. You can add them later in openmatrix.config.json")
408+
channels["none"] = True
409+
410+
config["communications"] = channels
411+
412+
342413
def configure_extras(config):
343414
"""Optional extras: timezone, memory."""
344415
tz = ask("Timezone", default="America/Los_Angeles")
@@ -429,7 +500,7 @@ def main():
429500
print(f" {DIM}Press Enter to accept defaults shown in [brackets].{RESET}")
430501
print(f" {DIM}You can re-run this anytime to change settings.{RESET}")
431502

432-
total = 8
503+
total = 9
433504
config = {
434505
"platform": "0pnMatrx",
435506
"database": {"path": "data/0pnmatrx.db"},
@@ -459,12 +530,16 @@ def main():
459530
step(6, total, "Gateway Server")
460531
configure_gateway(config)
461532

462-
# Step 7: Security
463-
step(7, total, "Security Settings")
533+
# Step 7: Communications
534+
step(7, total, "Communication Channels")
535+
configure_communications(config)
536+
537+
# Step 8: Security
538+
step(8, total, "Security Settings")
464539
configure_security(config)
465540

466-
# Step 8: Extras
467-
step(8, total, "Final Settings")
541+
# Step 9: Extras
542+
step(9, total, "Final Settings")
468543
configure_extras(config)
469544

470545
# Write and verify

0 commit comments

Comments
 (0)