Refactor Nexus One AI product structure and roadmap

- Add Workstation as an additive standalone category, kept out of
  TIER_ORDER so it never enters the Server S/M/L/Max upgrade ladder
- Add Server S/M/L/Max commercial labels for existing starter/basic/pro/max
  tiers (slugs, license format, and APIs unchanged)
- Rename portal UI terminology: Connectors -> MCP & Enterprise Connectors,
  Audit Log -> Governance & Audit, Model Manager -> Model Catalog,
  Agent Builder -> Agent Studio, Workflow Automation -> Workflow Designer,
  Multimodal Chat -> AI Workspace
- Fix branding.js workflow.html tier-gating bug and entry.yml missing tier var
- Document 7-capability platform roadmap and Workstation/Server structure
  in README.md and docs/README.md
- Ignore __pycache__/*.pyc build artifacts
This commit is contained in:
Jino Jose committed 2026-07-08 15:00:02 +05:30
1 parent e5b2496b97
commit 12d9ea84f6
58 files changed
+587 -366

No files matched your search

+1
View File
@@ -13,6 +13,7 @@
cuda_version: "12.4"
skip_roles: "" # comma-separated list of role names to skip (set by install.sh)
gpu_available: false
tier: "basic" # Server M (commercial label) — internal slug unchanged
roles:
- role: base
@@ -19,10 +19,46 @@ TIER_ALIASES = {
"basic tier": "basic",
"pro tier": "pro",
"max tier": "max",
# Server S/M/L/Max commercial labels — synonyms for the same four Server
# tiers/ranks above (starter/basic/pro/max). Additive only; TIER_ORDER and
# rank comparisons are unchanged.
"server s": "starter",
"server s tier": "starter",
"server m": "basic",
"server m tier": "basic",
"server l": "pro",
"server l tier": "pro",
"server max": "max",
"server max tier": "max",
}
STAGING_MAX_TIER = "basic"
SUPPORTED_SIGNATURE_ALGS = {"rsa-sha256", "sha256-rsa"}
# ── Product category: Workstation (standalone, NOT part of the Server ladder) ──
# Nexus One AI Workstation is a personal AI appliance (1-3 active users, 5 max),
# distinct from the Server S/M/L/Max ladder above (TIER_ORDER). It is additive:
# it does not appear in TIER_ORDER and must never be passed through tier_rank(),
# tier_lte(), min_tier(), evaluate_license()/build_tier_options() ladder logic —
# those functions and STAGING_MAX_TIER/TIER_ALIASES above are unchanged and only
# ever resolve to one of TIER_ORDER's four Server tiers. Workstation entitlement
# is looked up independently via TIER_MATRIX["workstation"] in main.py.
WORKSTATION_TIER = "workstation"
CATEGORY_SERVER = "server"
CATEGORY_WORKSTATION = "workstation"
WORKSTATION_ALIASES = {"workstation tier", "personal", "personal ai", "nexus one ai workstation"}
def is_workstation_tier(value):
"""True if `value` refers to the Workstation category (never a Server tier)."""
return (value or "").strip().lower() in ({WORKSTATION_TIER} | WORKSTATION_ALIASES)
def tier_category(value):
"""Return CATEGORY_WORKSTATION or CATEGORY_SERVER for a tier/category string.
Server tiers (starter/basic/pro/max — displayed as Server S/M/L/Max) rank via
TIER_ORDER; Workstation has no rank and is resolved independently."""
return CATEGORY_WORKSTATION if is_workstation_tier(value) else CATEGORY_SERVER
def utcnow_iso():
return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
+62 -1
View File
@@ -29,10 +29,15 @@ from apscheduler.triggers.cron import CronTrigger
from apscheduler.triggers.interval import IntervalTrigger
from cezen_license import (
STAGING_MAX_TIER,
WORKSTATION_TIER,
CATEGORY_SERVER,
CATEGORY_WORKSTATION,
collect_entitlement,
evaluate_license,
is_workstation_tier,
normalize_tier as license_normalize_tier,
read_json_file,
tier_category,
tier_lte,
write_json_file,
)
@@ -72,6 +77,8 @@ pwd_ctx = _passlib.CryptContext(schemes=["bcrypt"], deprecated="auto")
TIER_MATRIX = {
"starter": {
"label": "Starter",
"commercial_label": "Server S",
"category": CATEGORY_SERVER,
"positioning": "Private AI entry package for one department or small team.",
"max_users": 10,
"features": {
@@ -92,6 +99,8 @@ TIER_MATRIX = {
},
"basic": {
"label": "Basic",
"commercial_label": "Server M",
"category": CATEGORY_SERVER,
"positioning": "Department AI suite with users, RAG, meeting assistant, and audit basics.",
"max_users": 25,
"features": {
@@ -112,6 +121,8 @@ TIER_MATRIX = {
},
"pro": {
"label": "Pro",
"commercial_label": "Server L",
"category": CATEGORY_SERVER,
"positioning": "Production private AI platform for multiple teams and automation workflows.",
"max_users": 100,
"features": {
@@ -132,6 +143,8 @@ TIER_MATRIX = {
},
"max": {
"label": "Max",
"commercial_label": "Server Max",
"category": CATEGORY_SERVER,
"positioning": "Custom high-performance AI platform for large GPU systems and enterprise controls.",
"max_users": None,
"features": {
@@ -150,6 +163,43 @@ TIER_MATRIX = {
"deepspeed": "custom",
},
},
# ── Nexus One AI Workstation — additive, standalone product category ──
# NOT part of the Server S/M/L/Max ladder: intentionally absent from
# cezen_license.TIER_ORDER, so it is unreachable through the license
# evaluation/upgrade-path ladder (_current_tier, collect_entitlement,
# build_tier_options all resolve exclusively to starter/basic/pro/max).
# This entry exists purely so the Workstation feature set is documented
# and available for future, explicitly-built activation flows to read —
# it does not change behavior for any existing Server install/license.
"workstation": {
"label": "Workstation",
"commercial_label": "Nexus One AI Workstation",
"category": CATEGORY_WORKSTATION,
"positioning": "Personal AI appliance for individual developers, researchers, and knowledge workers — not a shared server.",
"max_users": 5,
"features": {
"portal": True,
"chat": True,
"rag": "personal",
"meeting_assistant": False,
"workflows": False,
"connectors": False,
"model_router": False,
"audit_report": False,
"backup_restore": True,
"guardrails": "basic",
"gpu_inference": True,
"fine_tuning": False,
"deepspeed": False,
"document_intelligence": True,
"personal_rag": True,
"prompt_studio": True,
"model_catalog": True,
"local_ai_workspace": True,
"api_access": True,
"personal_knowledge_base": True,
},
},
}
TIER_ALIASES = {
@@ -850,13 +900,22 @@ def _public_license_record(record: dict) -> dict:
return public
def _current_tier() -> str:
# Workstation is checked first and explicitly, rather than falling through
# to _normalize_tier() (which only knows the Server ladder and would
# silently alias an unrecognized "workstation" string to "basic"/Server M).
# This is what keeps Workstation from ever inheriting Server behavior.
if CEZEN_TIER:
if is_workstation_tier(CEZEN_TIER):
return WORKSTATION_TIER
return _normalize_tier(CEZEN_TIER)
entitlement = _entitlement_summary()
licensed_tier = (entitlement.get("licensed_tier") or "").strip()
if licensed_tier:
return _normalize_tier(licensed_tier)
return _normalize_tier(_setting_value("tier_label", "Basic"))
tier_label_setting = _setting_value("tier_label", "Basic")
if is_workstation_tier(tier_label_setting):
return WORKSTATION_TIER
return _normalize_tier(tier_label_setting)
def _entitlement_summary(feasibility: Optional[dict] = None) -> dict:
feasibility = feasibility or _cached_feasibility()
@@ -876,6 +935,8 @@ def _tier_payload() -> dict:
return {
"tier": tier,
"label": info["label"],
"commercial_label": info.get("commercial_label", info["label"]),
"category": info.get("category", CATEGORY_SERVER),
"locked": bool(CEZEN_TIER or license_record.get("allowed_tier") or license_record.get("tier")),
"positioning": info["positioning"],
"max_users": info["max_users"],