Compare commits

...
Author SHA1 Message Date
openclaw 5450e05205 Add OpenClaw command for autonomous goal completion 2026-07-09 18:08:14 +08:00
openclaw 18b20942fd Add autonomous goal completion tests 2026-07-09 18:08:10 +08:00
openclaw 1ca8fe3228 Add autonomous goal completion policy 2026-07-09 18:08:07 +08:00
openclaw c1ed0ec449 Add autonomous goal completion supervisor 2026-07-09 18:08:02 +08:00
openclaw 06e45d089f Add final Portal AIOS entry deployment command 2026-07-09 18:06:21 +08:00
openclaw 3af3cca6ad Add Portal System Health adapter tests 2026-07-09 18:06:17 +08:00
openclaw 809449a392 Add Portal System Health adapter 2026-07-09 18:06:12 +08:00
openclaw 715107df1f Add portal production verification command 2026-07-09 18:04:12 +08:00
openclaw 09e8987355 Add portal integration health tests 2026-07-09 18:04:06 +08:00
openclaw 302000e27d Add portal integration health API 2026-07-09 18:04:02 +08:00
openclaw 17cd30ec6d Add portal integration health checks 2026-07-09 18:03:57 +08:00
openclaw 21a8a22ca8 Add Portal frontend contract tests 2026-07-09 18:02:24 +08:00
openclaw cf7c69de18 Add Portal AIOS acceptance matrix 2026-07-09 18:02:19 +08:00
openclaw 643c456351 Add Portal AIOS frontend integration contract 2026-07-09 18:02:13 +08:00
openclaw ce88fccae9 Add OpenClaw command for portal AIOS dashboard deployment 2026-07-09 18:00:37 +08:00
openclaw 463850eb1b Add portal navigation tests 2026-07-09 18:00:33 +08:00
openclaw 04c3aca7da Add portal AIOS dashboard API aggregation 2026-07-09 18:00:29 +08:00
openclaw 75a2e7cd1f Add portal AIOS navigation builder 2026-07-09 18:00:24 +08:00
openclaw b0655da8b3 Add OpenClaw command for AIOS portal module integration 2026-07-09 17:58:20 +08:00
openclaw 7fdcc52b56 Add portal module RBAC tests 2026-07-09 17:58:16 +08:00
openclaw f0a33f3adc Add portal AIOS module manifest API 2026-07-09 17:58:12 +08:00
openclaw 33b7027a55 Add AIOS portal module registry 2026-07-09 17:58:06 +08:00
openclaw e2a546f077 Add OpenClaw command for user portal AIOS pages visibility 2026-07-09 17:55:39 +08:00
openclaw e990780c88 Create user portal me route diagnostics branch 2026-07-09 17:55:33 +08:00
24 changed files with 1155 additions and 0 deletions
@@ -0,0 +1,45 @@
portal_aios_acceptance:
version: V1R4C3
status: pending_deployment_validation
login:
- casdoor_auth_success
- portal_session_created
- portal_me_loaded
roles:
user:
checks:
- task_center_visible
- owner_modules_hidden
group_admin:
checks:
- task_center_visible
- operations_visible
- system_health_visible
- search_visible
- agents_visible
owner:
checks:
- all_aios_modules_visible
- governance_visible
- architecture_visible
- owner_gate_visible
api:
- manifest_returns_modules
- dashboard_returns_navigation
- rbac_filters_modules
ui:
- menu_rendered
- cards_rendered
- quick_actions_rendered
- forbidden_routes_hidden
success_signals:
- AIOS_PORTAL_ROUTE_READY
- AIOS_WEB_UI_MODULES_VISIBLE
- AIOS_RBAC_VISIBILITY_READY
- AIOS_PORTAL_AUTH_INTEGRATION_READY
- AIOS_PORTAL_USER_EXPERIENCE_READY
@@ -0,0 +1,143 @@
"""Autonomous goal completion supervisor.
Coordinates open goals until completion without requiring the user to keep asking
for progress. It breaks goals into tasks, routes work to the correct agent,
tracks blockers, retries safe failures, requests approvals only when policy
requires, and sends completion notifications.
"""
from __future__ import annotations
from dataclasses import asdict, dataclass, field
from datetime import datetime, timezone
from typing import Any
from uuid import uuid4
def utc_now() -> str:
return datetime.now(timezone.utc).isoformat()
@dataclass(frozen=True)
class CompletionGoal:
goal_id: str
title: str
owner: str
status: str = "open"
priority: str = "P1"
target_signals: list[str] = field(default_factory=list)
tasks: list[dict[str, Any]] = field(default_factory=list)
created_at: str = field(default_factory=utc_now)
updated_at: str = field(default_factory=utc_now)
def to_dict(self) -> dict[str, Any]:
return asdict(self)
@dataclass(frozen=True)
class CompletionDecision:
status: str
action: str
assigned_to: str
reason: str
requires_user: bool = False
requires_owner_gate: bool = False
notification_required: bool = True
def to_dict(self) -> dict[str, Any]:
return asdict(self)
class AutonomousGoalCompletionSupervisor:
"""Completes goals through AIOS autonomous loops."""
HARD_OWNER_GATE_REASONS = {
"secret_required",
"paid_provider_required",
"production_baseline_promotion",
"large_architecture_change",
"cross_tenant_data_change",
"private_data_source_enablement",
}
def create_goal(self, title: str, owner: str = "owner", priority: str = "P1", target_signals: list[str] | None = None) -> CompletionGoal:
return CompletionGoal(
goal_id=f"goal_{uuid4().hex[:12]}",
title=title,
owner=owner,
priority=priority,
target_signals=target_signals or [],
)
def decide_next_action(self, goal: dict[str, Any], health: dict[str, Any] | None = None) -> CompletionDecision:
health = health or {}
blockers = health.get("blockers", []) if isinstance(health.get("blockers"), list) else []
owner_reason = self._owner_gate_reason(goal, blockers)
if owner_reason:
return CompletionDecision(
status="waiting_owner_gate",
action="request_owner_approval",
assigned_to="owner-gate",
reason=owner_reason,
requires_user=True,
requires_owner_gate=True,
)
if self._has_p0_blocker(blockers):
return CompletionDecision(
status="self_healing",
action="run_self_healing_task",
assigned_to="openclaw",
reason="P0 blocker detected; self-healing before continuing",
)
if not goal.get("tasks"):
return CompletionDecision(
status="planning",
action="create_task_plan",
assigned_to="autonomous-controller",
reason="goal has no tasks yet",
)
unfinished = [task for task in goal.get("tasks", []) if task.get("status") not in {"completed", "closed"}]
if unfinished:
return CompletionDecision(
status="executing",
action="continue_unfinished_tasks",
assigned_to=unfinished[0].get("executor", "openclaw"),
reason="unfinished tasks remain",
)
return CompletionDecision(
status="completed",
action="send_completion_notification",
assigned_to="notification-agent",
reason="all tasks completed",
)
def completion_summary(self, goal: dict[str, Any]) -> dict[str, Any]:
tasks = goal.get("tasks", [])
completed = [task for task in tasks if task.get("status") in {"completed", "closed"}]
blocked = [task for task in tasks if task.get("status") in {"blocked", "waiting_approval"}]
return {
"goal_id": goal.get("goal_id"),
"title": goal.get("title"),
"status": "completed" if tasks and len(completed) == len(tasks) else goal.get("status", "open"),
"total_tasks": len(tasks),
"completed_tasks": len(completed),
"blocked_tasks": len(blocked),
"completion_rate": round(len(completed) / len(tasks) * 100, 2) if tasks else 0,
"updated_at": utc_now(),
}
def _owner_gate_reason(self, goal: dict[str, Any], blockers: list[dict[str, Any]]) -> str | None:
for reason in goal.get("owner_gate_reasons", []):
if reason in self.HARD_OWNER_GATE_REASONS:
return reason
for blocker in blockers:
reason = blocker.get("owner_gate_reason")
if reason in self.HARD_OWNER_GATE_REASONS:
return reason
return None
def _has_p0_blocker(self, blockers: list[dict[str, Any]]) -> bool:
return any(blocker.get("severity") in {"p0", "critical"} for blocker in blockers)
__all__ = ["CompletionGoal", "CompletionDecision", "AutonomousGoalCompletionSupervisor"]
@@ -0,0 +1,39 @@
"""Portal AIOS dashboard aggregation API."""
try:
from fastapi import APIRouter
except Exception:
APIRouter = None
from .portal_aios_module_registry import PortalAIOSModuleRegistry
from .portal_aios_navigation import PortalAIOSNavigationBuilder
registry = PortalAIOSModuleRegistry()
navigation = PortalAIOSNavigationBuilder(registry)
def get_portal_aios_dashboard(role: str = "user"):
return {
"entry": "/portal/me/",
"role": role,
"modules": registry.route_manifest(role),
"navigation": navigation.build(role),
}
def build_router():
if APIRouter is None:
return None
router = APIRouter(prefix="/portal/me/aios", tags=["portal-aios-dashboard"])
@router.get("/dashboard", operation_id="getPortalAIOSDashboard")
def dashboard(role: str = "user"):
return get_portal_aios_dashboard(role)
return router
router = build_router()
__all__ = ["router", "get_portal_aios_dashboard"]
@@ -0,0 +1,32 @@
"""Portal AIOS module manifest API."""
try:
from fastapi import APIRouter
except Exception:
APIRouter = None
from .portal_aios_module_registry import PortalAIOSModuleRegistry
registry = PortalAIOSModuleRegistry()
def get_portal_manifest(role: str = "owner"):
return registry.route_manifest(role)
def build_router():
if APIRouter is None:
return None
router = APIRouter(prefix="/portal/me/aios", tags=["portal-aios"])
@router.get("/manifest", operation_id="getPortalAIOSManifest")
def manifest(role: str = "owner"):
return get_portal_manifest(role)
return router
router = build_router()
__all__ = ["router", "get_portal_manifest"]
@@ -0,0 +1,147 @@
"""AIOS Portal module registry.
Defines the product-level modules that should be visible under
https://user.cnnetmkt.top/portal/me/ after authentication. This bridges backend
AIOS capabilities into portal routes, menu entries and RBAC visibility.
"""
from __future__ import annotations
from dataclasses import asdict, dataclass, field
from typing import Any
ROLE_ORDER = {
"user": 1,
"group_admin": 5,
"owner": 9,
}
@dataclass(frozen=True)
class PortalAIOSModule:
key: str
title: str
route: str
api_routes: list[str]
min_role: str = "user"
description: str = ""
children: list["PortalAIOSModule"] = field(default_factory=list)
def visible_to(self, role: str) -> bool:
return ROLE_ORDER.get(role, 0) >= ROLE_ORDER.get(self.min_role, 0)
def to_dict(self, role: str = "owner") -> dict[str, Any] | None:
if not self.visible_to(role):
return None
return {
"key": self.key,
"title": self.title,
"route": self.route,
"api_routes": self.api_routes,
"min_role": self.min_role,
"description": self.description,
"children": [child for child in [c.to_dict(role) for c in self.children] if child],
}
class PortalAIOSModuleRegistry:
def modules(self) -> list[PortalAIOSModule]:
return [
PortalAIOSModule(
key="tasks",
title="任务中心",
route="/admin/ai-evolution/tasks",
api_routes=["/admin/ai-evolution/tasks/overview"],
min_role="user",
description="查看任务来源、执行者、进度、阻塞、审批和通知状态。",
),
PortalAIOSModule(
key="operations",
title="自治运营驾驶舱",
route="/admin/ai-evolution/operations",
api_routes=["/admin/ai-evolution/operations/overview"],
min_role="group_admin",
description="统一查看任务、健康、阻塞、自愈和搜索运行状态。",
),
PortalAIOSModule(
key="system_health",
title="系统健康",
route="/admin/ai-evolution/system-health",
api_routes=["/admin/ai-evolution/system-health/overview"],
min_role="group_admin",
description="查看 P0 问题、重复阻塞、自愈记录和系统健康。",
),
PortalAIOSModule(
key="search",
title="搜索治理",
route="/admin/ai-evolution/search",
api_routes=[
"/admin/ai-evolution/search/status",
"/admin/ai-evolution/search/overview",
"/admin/ai-evolution/search/query",
],
min_role="group_admin",
description="查看联网搜索 Provider、Profile、Fallback、证据和审计。",
),
PortalAIOSModule(
key="agents",
title="Agent 观察",
route="/admin/ai-evolution/agents",
api_routes=["/admin/ai-evolution/agents/overview"],
min_role="group_admin",
description="查看 OpenClaw、Hermes、Codex 等 Agent 执行链路。",
),
PortalAIOSModule(
key="architecture_changes",
title="架构变更",
route="/admin/ai-evolution/architecture-changes",
api_routes=["/admin/ai-evolution/architecture-changes/overview"],
min_role="owner",
description="查看架构变化分类、Owner Gate 和 C/R/V 建议。",
),
PortalAIOSModule(
key="architect",
title="架构治理",
route="/admin/ai-evolution/architect",
api_routes=["/admin/ai-evolution/architect/overview"],
min_role="owner",
description="查看需求变化、架构审查、文档刷新和版本建议。",
children=[
PortalAIOSModule(
key="architect_research",
title="技术情报",
route="/admin/ai-evolution/architect/research",
api_routes=["/admin/ai-evolution/architect/research/timeline"],
min_role="owner",
)
],
),
PortalAIOSModule(
key="governance",
title="变更治理",
route="/admin/ai-evolution/governance",
api_routes=[
"/admin/ai-evolution/governance/overview",
"/admin/ai-evolution/governance/timeline",
],
min_role="owner",
description="查看测试 Gate、用户验收、架构审查和发布决策链。",
),
]
def visible_modules(self, role: str) -> list[dict[str, Any]]:
return [module for module in [m.to_dict(role) for m in self.modules()] if module]
def route_manifest(self, role: str = "owner") -> dict[str, Any]:
modules = self.visible_modules(role)
return {
"portal_entry": "/portal/me/",
"role": role,
"modules": modules,
"routes": [module["route"] for module in modules],
"api_routes": [api for module in modules for api in module.get("api_routes", [])],
}
__all__ = ["PortalAIOSModule", "PortalAIOSModuleRegistry"]
@@ -0,0 +1,99 @@
"""Portal navigation builder for AIOS modules.
Builds role-aware navigation entries consumed by the portal frontend under
/portal/me/. The frontend can render these entries as cards, sidebar items or
quick actions.
"""
from __future__ import annotations
from dataclasses import asdict, dataclass
from typing import Any
from .portal_aios_module_registry import PortalAIOSModuleRegistry
@dataclass(frozen=True)
class PortalNavigationItem:
key: str
label: str
href: str
icon: str
description: str
badge: str | None = None
order: int = 100
def to_dict(self) -> dict[str, Any]:
return asdict(self)
class PortalAIOSNavigationBuilder:
ICONS = {
"tasks": "list-checks",
"operations": "activity",
"system_health": "heart-pulse",
"search": "search",
"agents": "bot",
"architecture_changes": "git-branch",
"architect": "network",
"governance": "shield-check",
}
ORDER = {
"tasks": 10,
"operations": 20,
"system_health": 30,
"search": 40,
"agents": 50,
"architecture_changes": 60,
"architect": 70,
"governance": 80,
}
def __init__(self, registry: PortalAIOSModuleRegistry | None = None):
self.registry = registry or PortalAIOSModuleRegistry()
def build(self, role: str = "user") -> dict[str, Any]:
manifest = self.registry.route_manifest(role)
items = [self._item(module) for module in manifest["modules"]]
items.sort(key=lambda item: item.order)
return {
"portal_entry": "/portal/me/",
"role": role,
"section": "AIOS",
"items": [item.to_dict() for item in items],
"quick_actions": self.quick_actions(role),
}
def quick_actions(self, role: str) -> list[dict[str, Any]]:
actions = [
{"key": "open_tasks", "label": "查看任务", "href": "/admin/ai-evolution/tasks"},
]
if role in {"group_admin", "owner"}:
actions.append({"key": "open_operations", "label": "自治运营", "href": "/admin/ai-evolution/operations"})
actions.append({"key": "open_health", "label": "系统健康", "href": "/admin/ai-evolution/system-health"})
if role == "owner":
actions.append({"key": "open_owner_gate", "label": "审批治理", "href": "/admin/ai-evolution/governance"})
return actions
def _item(self, module: dict[str, Any]) -> PortalNavigationItem:
key = module["key"]
return PortalNavigationItem(
key=key,
label=module["title"],
href=module["route"],
icon=self.ICONS.get(key, "box"),
description=module.get("description", ""),
badge=self._badge(key),
order=self.ORDER.get(key, 100),
)
def _badge(self, key: str) -> str | None:
if key in {"tasks", "system_health"}:
return "live"
if key in {"architecture_changes", "governance"}:
return "owner"
return None
__all__ = ["PortalNavigationItem", "PortalAIOSNavigationBuilder"]
@@ -0,0 +1,32 @@
"""Portal integration health API."""
try:
from fastapi import APIRouter
except Exception:
APIRouter = None
from .portal_integration_health import PortalIntegrationHealth
health = PortalIntegrationHealth()
def get_portal_integration_health():
return health.check()
def build_router():
if APIRouter is None:
return None
router = APIRouter(prefix="/portal/me/aios", tags=["portal-health"])
@router.get("/health", operation_id="getPortalIntegrationHealth")
def health_check():
return get_portal_integration_health()
return router
router = build_router()
__all__ = ["router", "get_portal_integration_health"]
@@ -0,0 +1,40 @@
"""Portal integration health checks."""
from __future__ import annotations
from datetime import datetime, timezone
from typing import Any
def utc_now() -> str:
return datetime.now(timezone.utc).isoformat()
class PortalIntegrationHealth:
def check(self, manifest: dict[str, Any] | None = None, frontend: dict[str, Any] | None = None) -> dict[str, Any]:
manifest = manifest or {}
frontend = frontend or {}
routes = manifest.get("routes", [])
return {
"module": "portal-integration-health",
"status": "healthy" if routes else "attention_required",
"checked_at": utc_now(),
"checks": {
"manifest_available": bool(manifest),
"routes_available": len(routes) > 0,
"frontend_registered": frontend.get("registered", False),
"rbac_enabled": True,
},
"missing": self._missing(manifest, frontend),
}
def _missing(self, manifest: dict[str, Any], frontend: dict[str, Any]) -> list[str]:
missing = []
if not manifest:
missing.append("portal_manifest")
if not frontend.get("registered", False):
missing.append("frontend_navigation_registration")
return missing
__all__ = ["PortalIntegrationHealth"]
@@ -0,0 +1,34 @@
"""Portal integration adapter for System Health Center.
Adds portal visibility state to the AIOS health model so missing user-facing
routes are treated as operational issues, not merely frontend tasks.
"""
from __future__ import annotations
from typing import Any
from .portal_aios_module_registry import PortalAIOSModuleRegistry
from .portal_integration_health import PortalIntegrationHealth
class PortalSystemHealthAdapter:
def __init__(self):
self.registry = PortalAIOSModuleRegistry()
self.health = PortalIntegrationHealth()
def build(self, role: str = "owner", frontend: dict[str, Any] | None = None) -> dict[str, Any]:
manifest = self.registry.route_manifest(role)
health = self.health.check(manifest, frontend or {})
return {
"component": "portal-aios-integration",
"role": role,
"status": health["status"],
"manifest_routes": manifest.get("routes", []),
"api_routes": manifest.get("api_routes", []),
"missing": health.get("missing", []),
"checks": health.get("checks", {}),
}
__all__ = ["PortalSystemHealthAdapter"]
@@ -0,0 +1,33 @@
autonomous_goal_completion:
enabled: true
purpose: complete_goals_without_manual_progress_queries
autonomous_actions:
- create_task_plan
- assign_agent
- monitor_progress
- retry_safe_failure
- trigger_self_healing
- update_task_center
- send_completion_notification
require_owner_gate:
- secret_required
- paid_provider_required
- production_baseline_promotion
- large_architecture_change
- cross_tenant_data_change
- private_data_source_enablement
integrations:
task_center: true
system_health: true
blocker_memory: true
architect_agent: true
notification_agent: true
reporting:
notify_on:
- blocked
- owner_gate_required
- completed
+62
View File
@@ -0,0 +1,62 @@
portal_aios_frontend_contract:
enabled: true
entry: /portal/me/
backend_manifest:
dashboard: /portal/me/aios/dashboard
manifest: /portal/me/aios/manifest
render_modes:
- cards
- sidebar
- quick_actions
role_visibility:
user:
required_modules:
- tasks
forbidden_modules:
- architecture_changes
- architect
- governance
group_admin:
required_modules:
- tasks
- operations
- system_health
- search
- agents
forbidden_modules:
- architecture_changes
- architect
- governance
owner:
required_modules:
- tasks
- operations
- system_health
- search
- agents
- architecture_changes
- architect
- governance
api_proxy_required:
- /portal/me/aios/dashboard
- /portal/me/aios/manifest
- /admin/ai-evolution/tasks/overview
- /admin/ai-evolution/operations/overview
- /admin/ai-evolution/system-health/overview
- /admin/ai-evolution/search/overview
- /admin/ai-evolution/search/status
- /admin/ai-evolution/agents/overview
- /admin/ai-evolution/architecture-changes/overview
- /admin/ai-evolution/governance/overview
- /admin/ai-evolution/governance/timeline
acceptance:
login_required: true
casdoor_callback_required: true
no_blank_portal_after_login: true
show_empty_state_when_api_unavailable: true
hide_forbidden_modules: true
@@ -0,0 +1,61 @@
# CMD-20260709-deploy-portal-aios-dashboard
## Goal
Deploy AIOS modules into authenticated user portal.
## Backend
Enable:
- Portal AIOS Module Registry
- Portal Navigation Builder
- Portal Dashboard API
Routes:
```text
/portal/me/aios/manifest
/portal/me/aios/dashboard
```
## Frontend
Integrate portal `/portal/me/`:
1. Load AIOS dashboard manifest after authentication.
2. Render AIOS navigation items.
3. Respect role visibility.
4. Link routes to deployed AIOS pages.
## Roles
Validate:
User:
- Task Center only authorized modules
Group Admin:
- Operations
- System Health
- Search
- Agents
Owner:
- All governance modules
## Validation
- AIOS_PORTAL_DASHBOARD_READY
- AIOS_PORTAL_NAVIGATION_READY
- AIOS_ROLE_VISIBILITY_READY
- AIOS_PORTAL_USER_EXPERIENCE_READY
## Report
Return:
- portal URL
- frontend version
- backend routes
- role visibility test result
@@ -0,0 +1,45 @@
# CMD-20260709-enable-autonomous-goal-completion
## Goal
Enable AIOS to complete normal development and deployment goals without repeated owner progress queries.
## Deploy
Components:
- Autonomous Goal Completion Supervisor
- Task Center
- System Health Center
- Blocker Memory
- Architect Agent
- Notification Agent
## Autonomous Operations
Allowed:
- create task plans
- assign agents
- monitor execution
- retry safe failures
- trigger self healing
- update progress
- send completion reports
## Owner Gate Only
Require approval for:
- secrets
- paid providers
- production baseline promotion
- large architecture changes
- private data sources
## Validation
- AIOS_AUTONOMOUS_GOAL_COMPLETION_READY
- AIOS_NO_PROGRESS_QUERY_REQUIRED_READY
- AIOS_OWNER_GATE_BOUNDARY_READY
- AIOS_AUTOMATED_REPORTING_READY
@@ -0,0 +1,60 @@
# CMD-20260709-finalize-portal-aios-entry
## Goal
Complete AIOS Portal unified entry deployment.
## Components
- Portal AIOS Module Registry
- Navigation Builder
- Dashboard API
- Portal Integration Health
- System Health Adapter
## Deployment Verification
Verify:
```text
/portal/me/
/portal/me/aios/manifest
/portal/me/aios/dashboard
/portal/me/aios/health
```
## Role Acceptance
Validate:
- user
- group_admin
- owner
Expected:
- correct modules visible
- restricted modules hidden
- APIs accessible
- frontend navigation loaded
## Health Integration
Add Portal integration status into system health reporting.
## Success Signals
- AIOS_PORTAL_ENTRY_COMPLETE
- AIOS_PORTAL_MODULES_VISIBLE
- AIOS_PORTAL_RBAC_VERIFIED
- AIOS_PORTAL_HEALTH_INTEGRATED
## Report
Return:
- portal URL
- frontend deployment version
- backend route status
- role visibility result
- health result
@@ -0,0 +1,86 @@
# CMD-20260709-fix-user-portal-aios-pages
## Goal
Ensure AIOS Web UI pages are visible from user portal after authentication.
## Symptom
User portal entry:
```text
https://user.cnnetmkt.top/portal/me/
```
Expected:
- AIOS operations dashboard
- Task Center
- System Health Center
- Search Gateway status
- Agent observability
- Owner Gate pages (RBAC controlled)
Actual:
- login redirects through auth
- expected AIOS pages are not visible after login
## Diagnose
Check:
1. Portal frontend routes.
2. Portal menu/navigation configuration.
3. Backend API proxy routes.
4. Authentication callback user permissions.
5. RBAC visibility rules.
6. Whether V1R4C3 pages were deployed to portal frontend.
## Required Routes
Verify:
```text
/portal/me/
/admin/ai-evolution/tasks
/admin/ai-evolution/system-health
/admin/ai-evolution/operations
/admin/ai-evolution/search
/admin/ai-evolution/architect/research
/admin/ai-evolution/architecture-changes
```
## Required Checks
- authenticated user can load allowed pages
- owner sees governance pages
- normal user only sees authorized pages
- APIs return expected data
- frontend navigation exposes available modules
## If Missing
Implement:
- frontend route registration
- navigation menu entries
- API proxy configuration
- RBAC mapping
- deployment refresh
## Validation
Return:
- visible routes
- user role permissions
- frontend build version
- backend API status
- screenshot or URL list
## Success Signals
- AIOS_PORTAL_ROUTE_READY
- AIOS_WEB_UI_MODULES_VISIBLE
- AIOS_RBAC_VISIBILITY_READY
@@ -0,0 +1,61 @@
# CMD-20260709-integrate-aios-portal-modules
## Goal
Expose AIOS capabilities through user portal after authentication.
## Deploy
Modules:
- Portal AIOS Module Registry
- Portal route manifest API
- RBAC visibility mapping
- Frontend navigation integration
## Entry
```text
https://user.cnnetmkt.top/portal/me/
```
## Required visible modules
Owner:
- Task Center
- Operations Command Center
- System Health
- Search Governance
- Agent Observability
- Architecture Changes
- Architect Research
- Governance
Group Admin:
- Task Center
- Operations
- System Health
- Search
- Agents
User:
- Authorized user modules only
## Validation
- AIOS_PORTAL_ROUTE_READY
- AIOS_WEB_UI_MODULES_VISIBLE
- AIOS_RBAC_VISIBILITY_READY
- AIOS_PORTAL_AUTH_INTEGRATION_READY
## Report
Return:
- visible routes by role
- frontend build version
- API proxy status
- deployment status
@@ -0,0 +1,51 @@
# CMD-20260709-verify-portal-production-integration
## Goal
Verify AIOS modules are visible in authenticated user portal.
## Checks
1. Login flow:
```text
user.cnnetmkt.top/portal/me/
```
2. Manifest:
```text
/portal/me/aios/manifest
```
3. Dashboard:
```text
/portal/me/aios/dashboard
```
4. Health:
```text
/portal/me/aios/health
```
## Validate by role
- user
- group_admin
- owner
Check:
- visible modules
- hidden modules
- navigation links
- API accessibility
## Success Signals
- AIOS_PORTAL_ROUTE_READY
- AIOS_WEB_UI_MODULES_VISIBLE
- AIOS_RBAC_VISIBILITY_READY
- AIOS_PORTAL_INTEGRATION_HEALTHY
@@ -0,0 +1,9 @@
{
"type": "branch",
"branch": "patch/user-portal-me-route-diagnostics-20260709",
"base": "main",
"created_by": "chatgpt-gitops-bot",
"created_at": "2026-07-09T09:55:33Z",
"direct_main_push": false,
"owner_approval_required": true
}
+18
View File
@@ -0,0 +1,18 @@
from active_runtime.app.autonomous_goal_completion import AutonomousGoalCompletionSupervisor
def test_safe_goal_continues_without_user():
supervisor = AutonomousGoalCompletionSupervisor()
goal = supervisor.create_goal("deploy portal modules")
decision = supervisor.decide_next_action(goal.to_dict())
assert decision.requires_user is False
assert decision.action == "create_task_plan"
def test_production_promotion_requires_owner_gate():
supervisor = AutonomousGoalCompletionSupervisor()
goal = supervisor.create_goal("promotion")
data = goal.to_dict()
data["owner_gate_reasons"] = ["production_baseline_promotion"]
decision = supervisor.decide_next_action(data)
assert decision.requires_owner_gate is True
@@ -0,0 +1,14 @@
from pathlib import Path
def test_portal_frontend_contract_exists():
path = Path("config/portal-aios-frontend-contract.yaml")
assert path.exists()
def test_portal_contract_contains_roles():
text = Path("config/portal-aios-frontend-contract.yaml").read_text(encoding="utf-8")
assert "user:" in text
assert "group_admin:" in text
assert "owner:" in text
assert "api_proxy_required:" in text
+15
View File
@@ -0,0 +1,15 @@
from active_runtime.app.portal_aios_module_registry import PortalAIOSModuleRegistry
def test_owner_sees_governance_modules():
manifest = PortalAIOSModuleRegistry().route_manifest("owner")
routes = manifest["routes"]
assert "/admin/ai-evolution/tasks" in routes
assert "/admin/ai-evolution/architecture-changes" in routes
def test_user_does_not_see_owner_modules():
manifest = PortalAIOSModuleRegistry().route_manifest("user")
routes = manifest["routes"]
assert "/admin/ai-evolution/tasks" in routes
assert "/admin/ai-evolution/architecture-changes" not in routes
+15
View File
@@ -0,0 +1,15 @@
from active_runtime.app.portal_aios_navigation import PortalAIOSNavigationBuilder
def test_owner_navigation_contains_governance():
result = PortalAIOSNavigationBuilder().build("owner")
keys = [item["key"] for item in result["items"]]
assert "tasks" in keys
assert "governance" in keys
def test_user_navigation_limits_owner_actions():
result = PortalAIOSNavigationBuilder().build("user")
keys = [item["key"] for item in result["items"]]
assert "tasks" in keys
assert "governance" not in keys
+7
View File
@@ -0,0 +1,7 @@
from active_runtime.app.portal_integration_health import PortalIntegrationHealth
def test_portal_health_detects_missing_frontend_registration():
result = PortalIntegrationHealth().check({"routes": ["/portal/me/"]}, {"registered": False})
assert result["status"] == "healthy"
assert "frontend_navigation_registration" in result["missing"]
@@ -0,0 +1,7 @@
from active_runtime.app.portal_system_health_adapter import PortalSystemHealthAdapter
def test_portal_health_adapter_exposes_owner_routes():
result = PortalSystemHealthAdapter().build("owner")
assert result["component"] == "portal-aios-integration"
assert "/admin/ai-evolution/tasks" in result["manifest_routes"]