Compare commits

..
Author SHA1 Message Date
openclaw 12d09b1dea proposal: start V1R4C4 SR-01 Gitea branch sync fix 2026-07-10 01:42:12 +08:00
25 changed files with 131 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,131 @@
# V1R4C4 SR-01: Gitea Branch Sync Fix
Status: started
Priority: P0
Risk: medium
Baseline dependency: V1R4C3
## Decision
Start V1R4C4 with SR-01 only.
SR-04 Portal AIOS Integration Merge remains deferred and is not part of this execution scope.
## Background
V1R4C3 completed the immediate branch_sync mitigation by changing branch synchronization to use `git ls-remote` instead of depending on the Gitea branch API pagination path.
That mitigation avoids the user-visible failure path, but it does not fully certify or eliminate the root reliability issue:
```text
bare repository refs
!=
Gitea branch metadata / DB index
!=
Gitea branch API visible state
```
SR-01 exists to validate and fix the root problem category: Gitea branch metadata/index drift from the bare repository state.
## Scope
SR-01 includes:
1. Confirm current branch_sync no longer depends on Gitea API pagination.
2. Validate that Gitea DB branch metadata is consistent with bare repository refs.
3. Add or activate consistency verification around branch metadata drift.
4. Ensure autonomous operations do not continue mutating state when drift is detected.
5. Produce a repeatable acceptance test for future incidents.
SR-01 excludes:
- Portal AIOS Integration Merge.
- Search Gateway real provider binding.
- Broad P1 capability merges.
- Bulk patch merge or branch deletion.
## Required Checks
### Branch sync path
Verify branch_sync source of truth:
```text
git ls-remote / bare repository refs
```
The Gitea branch API must not be the mandatory source of truth for synchronization.
### Gitea consistency path
Verify equality between:
```text
bare repository refs count
Gitea branch live metadata count
Gitea branch API paginated visible count
```
Any mismatch must be treated as reliability drift.
### Safe-mode behavior
When drift is detected:
1. Stop autonomous mutations.
2. Preserve read-only diagnostics.
3. Emit safe-mode marker.
4. Require controlled recovery before mutation resumes.
## Acceptance Criteria
SR-01 is complete when all of the following are true:
1. branch_sync continues to work without Gitea branch API pagination dependency.
2. Gitea branch metadata drift can be detected deterministically.
3. Drift causes autonomous safe mode instead of continued mutation.
4. Recovery procedure includes minimal repair, not default restart.
5. Runtime acceptance passes:
```text
getRuntimeStatus
->
getBaseline
->
createBranch
->
createPatch
```
Expected results:
- runtime status is active;
- baseline reads V1R4C3 or later;
- createBranch returns commit/rev/sync status;
- createPatch returns commit/rev/sync status.
## Execution Order
1. Open SR-01 patch branch.
2. Review V1R4C3 branch_sync behavior.
3. Integrate Gitea branch consistency sentinel and safe-mode gate.
4. Run runtime acceptance.
5. If clean, prepare V1R4C4 reliability baseline proposal.
## Follow-on Gates
SR-02 Watcher State Cleanup may start after SR-01 acceptance is green.
SR-03 Search Gateway Real Provider Binding may start after SR-01 confirms GitOps/Gitea reliability is stable enough for non-P0 work.
SR-04 Portal AIOS Integration Merge remains deferred pending explicit approval.
## Safety Rules
- Do not bulk merge old patches.
- Do not delete remote branches during SR-01 unless the branch consistency sentinel is already deployed and healthy.
- Do not restart Gitea unless process-level failure is proven.
- Do not modify Gitea DB without backup and owner/admin approval.
@@ -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"]