Compare commits

..
Author SHA1 Message Date
openclaw 1789572efe decision: gate SR-04 behind V1R4C4 reliability freeze 2026-07-10 09:14:40 +08:00
25 changed files with 116 additions and 1155 deletions
@@ -1,45 +0,0 @@
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
@@ -1,143 +0,0 @@
"""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"]
@@ -1,39 +0,0 @@
"""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"]
@@ -1,32 +0,0 @@
"""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"]
@@ -1,147 +0,0 @@
"""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"]
@@ -1,99 +0,0 @@
"""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"]
@@ -1,32 +0,0 @@
"""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"]
@@ -1,40 +0,0 @@
"""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"]
@@ -1,34 +0,0 @@
"""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"]
@@ -1,33 +0,0 @@
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
@@ -1,62 +0,0 @@
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,116 @@
# V1R4C4 Reliability Freeze Before SR-04
Status: accepted
Decision date: 2026-07-10
Current baseline: V1R4C3
## Decision
V1R4C4 will complete reliability freeze before merging Portal AIOS Integration.
SR-04 remains `activation-ready`, but it must not be merged or deployed before SR-01 and SR-02 are complete and accepted.
## Scope Ordering
```text
SR-01 Gitea Branch Sync Fix
↓
SR-02 Watcher State Cleanup
↓
SR-04 Portal AIOS Integration Merge
```
## SR-01 Gate
SR-01 must complete the P0 reliability work for Gitea branch sync and metadata drift.
Required outcomes:
1. branch_sync remains independent of Gitea branch API pagination.
2. bare repository refs, Gitea DB branch metadata, and Gitea API visible state are checked for consistency.
3. branch metadata drift triggers autonomous safe mode.
4. recovery procedure favors minimal repair over default restart.
5. runtime acceptance passes.
Acceptance sequence:
```text
getRuntimeStatus
->
getBaseline
->
createBranch
->
createPatch
```
## SR-02 Gate
SR-02 must complete watcher state cleanup integration.
Current known test signal:
```text
11 / 11 tests pass
```
Required outcomes:
1. stuck command detection reads parsed timestamps correctly.
2. `.json` command state files are handled correctly.
3. `.md` command state files are handled correctly.
4. file mtime semantics are aligned with stored stuck timestamps in tests.
5. watcher cleanup is integrated behind the reliability assumptions introduced by SR-01.
## SR-04 Status
SR-04 remains:
```text
activation-ready
```
But SR-04 is explicitly blocked from merge/deploy until SR-01 and SR-02 gates are green.
SR-04 may continue with planning, diff review, and acceptance design, but may not perform production portal deployment.
## Reason
The user-visible portal feature gap is real, but the system recently experienced a stop-the-line reliability incident involving Gitea branch metadata drift. Reliability freeze must complete first to avoid combining production portal changes with unresolved GitOps/Gitea consistency risk.
## Allowed During Freeze
Allowed:
- SR-04 planning;
- SR-04 diff review;
- frontend/backend contract review;
- RBAC acceptance design;
- non-production validation;
- documentation updates.
Not allowed before SR-01/SR-02 acceptance:
- merging SR-04 to main;
- deploying SR-04 to production;
- bypassing RBAC to expose modules;
- combining portal integration with Gitea DB repair;
- bulk merging old portal branches.
## SR-04 Release Gate
SR-04 may enter merge/deploy only after:
1. SR-01 acceptance is green.
2. SR-02 acceptance is green.
3. GitOps runtime acceptance is green.
4. Gitea consistency sentinel is deployed or explicitly deferred with owner approval.
5. Portal RBAC acceptance plan is approved.
## Final Rule
V1R4C4 is reliability-first.
Portal AIOS Integration remains prepared but gated until reliability freeze is complete.
@@ -1,61 +0,0 @@
# 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
@@ -1,45 +0,0 @@
# 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
@@ -1,60 +0,0 @@
# 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
@@ -1,86 +0,0 @@
# 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
@@ -1,61 +0,0 @@
# 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
@@ -1,51 +0,0 @@
# 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
@@ -1,9 +0,0 @@
{
"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
@@ -1,18 +0,0 @@
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
@@ -1,14 +0,0 @@
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
@@ -1,15 +0,0 @@
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
@@ -1,15 +0,0 @@
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
@@ -1,7 +0,0 @@
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"]
@@ -1,7 +0,0 @@
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"]