Compare commits

...
3 Commits
12 changed files with 1125 additions and 2 deletions
+1 -1
View File
@@ -44,5 +44,5 @@
"/api",
"/hook"
],
"updated_at": "2026-07-06T07:13:43.274132+00:00"
"updated_at": "2026-07-06T07:16:01.842497+00:00"
}
+363
View File
@@ -0,0 +1,363 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="/data/aios-gitops"
ZIP_NAME="AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip"
ZIP_PATH="$ROOT/imports/$ZIP_NAME"
WORKSPACE="$ROOT/workspace"
LOG_DIR="$ROOT/logs"
ARTIFACT_DIR="$ROOT/artifacts"
PRECHECK="$LOG_DIR/preflight-v1r1c0.md"
RUN_LOG="$LOG_DIR/gitops-v1r1c0-migration.log"
FAILED_REPORT="$ARTIFACT_DIR/AIOS_V1R1C0_ONLINE_BASELINE_FAILED.md"
ACCEPT_REPORT="$ARTIFACT_DIR/AIOS_V1R1C0_ONLINE_BASELINE_ACCEPTANCE.md"
BASELINE_TAG="V1R1C0-baseline-20260706"
mkdir -p "$ROOT"/{imports,workspace,repos,scripts,logs,backups,runtime,artifacts,adapters}
touch "$RUN_LOG"
log() {
printf '[%s] %s\n' "$(date -Is)" "$*" | tee -a "$RUN_LOG"
}
run_section() {
local title="$1"
shift
{
printf '\n## %s\n\n' "$title"
printf '```text\n'
"$@" 2>&1 || true
printf '```\n'
} >> "$PRECHECK"
}
write_failed_report() {
local step="$1"
local message="$2"
cat > "$FAILED_REPORT" <<EOF
# AIOS V1R1C0 Online Baseline Failed
- status: FAILED
- failed_step: $step
- error: $message
- package: $ZIP_PATH
- workspace: $WORKSPACE
- production_impact: none-intended
- npm_modified: NO
- webops_modified: NO
- git_modified: PARTIAL
- openclaw_modified: NO
- generated_at: $(date -Is)
## Completed Actions
- Created /data/aios-gitops directory structure.
- Generated preflight report when possible.
- Preserved original ZIP if present.
- Stopped before production routing changes.
## Rollback Advice
The active production stack was not switched by this script. Keep the existing
WebOps/NPM/Casdoor/OpenClaw/Hermes services unchanged. Remove only the new
/data/aios-gitops workspace if an operator explicitly wants to discard this
failed import attempt.
## Next Step
Fix the failed step, then rerun the migration script. Do not treat this state
as an online baseline.
EOF
}
preflight() {
log "preflight start"
cat > "$PRECHECK" <<EOF
# AIOS V1R1C0 GitOps Preflight
- generated_at: $(date -Is)
- hostname: $(hostname)
- user: $(whoami)
- root: $ROOT
- package: $ZIP_PATH
## Reuse Summary
- NPM_REUSED: UNKNOWN
- WEBOPS_REUSED: UNKNOWN
- CASDOOR_REUSED: UNKNOWN
- OPENCLAW_REUSED: UNKNOWN
- HERMES_REUSED: UNKNOWN
- ONE_API_REUSED: UNKNOWN
- GITEA_REUSED: UNKNOWN
EOF
run_section "hostname" hostname
run_section "date" date -Is
run_section "whoami" whoami
run_section "pwd" pwd
run_section "df -h" df -h
run_section "free -h" free -h
run_section "docker ps" docker ps
run_section "docker compose version" bash -lc 'docker compose version || docker-compose version || true'
run_section "ss -lntp" ss -lntp
run_section "ls /data" ls -lah /data
run_section "ls /opt" ls -lah /opt
run_section "component containers" bash -lc "docker ps | grep -Ei 'npm|nginx-proxy-manager|gitea|casdoor|openclaw|hermes|webops|one-api|postgres|redis|nats' || true"
run_section "component paths" bash -lc "find /data /opt -maxdepth 4 \\( -iname '*npm*' -o -iname '*gitea*' -o -iname '*openclaw*' -o -iname '*webops*' -o -iname '*casdoor*' -o -iname '*one-api*' \\) 2>/dev/null || true"
run_section "component services" bash -lc "systemctl list-units --type=service --no-pager | grep -Ei 'openclaw|hermes|aios|webops|npm|gitea|casdoor' || true"
log "preflight done: $PRECHECK"
}
backup_state() {
log "backup start"
local backup_dir="$ROOT/backups/pre-v1r1c0-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$backup_dir"
cp -a /data/agent "$backup_dir/data-agent" 2>/dev/null || true
cp -a /data/aios "$backup_dir/data-aios" 2>/dev/null || true
cp -a /opt/aios "$backup_dir/opt-aios" 2>/dev/null || true
cp -a /etc/systemd/system "$backup_dir/systemd-system" 2>/dev/null || true
docker ps > "$backup_dir/docker-ps.txt" 2>/dev/null || true
ss -lntp > "$backup_dir/ports.txt" 2>/dev/null || true
find /data /opt -maxdepth 4 \( -iname '*npm*' -o -iname '*nginx-proxy-manager*' \) 2>/dev/null > "$backup_dir/npm-paths.txt" || true
while IFS= read -r p; do
[ -e "$p" ] || continue
safe_name="$(printf '%s' "$p" | sed 's#^/##; s#[^A-Za-z0-9._-]#_#g')"
cp -a "$p" "$backup_dir/$safe_name" 2>/dev/null || true
done < "$backup_dir/npm-paths.txt"
printf '%s\n' "$backup_dir" > "$ROOT/runtime/latest-backup-dir.txt"
log "backup done: $backup_dir"
}
import_zip() {
log "import start"
if [ ! -f "$ZIP_PATH" ]; then
write_failed_report "locate_zip" "BLOCKED: missing $ZIP_NAME"
log "BLOCKED: missing $ZIP_NAME"
exit 2
fi
mkdir -p "$WORKSPACE"
resolved="$(readlink -f "$WORKSPACE")"
if [ "$resolved" != "$WORKSPACE" ]; then
write_failed_report "workspace_resolve" "Unexpected workspace path: $resolved"
exit 3
fi
find "$WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +
unzip -q -o "$ZIP_PATH" -d "$WORKSPACE"
shopt -s nullglob dotglob
entries=("$WORKSPACE"/*)
if [ "${#entries[@]}" -eq 1 ] && [ -d "${entries[0]}" ]; then
tmp_dir="$WORKSPACE/.flatten-tmp"
mv "${entries[0]}" "$tmp_dir"
shopt -s dotglob
mv "$tmp_dir"/* "$WORKSPACE"/
rmdir "$tmp_dir"
fi
chmod +x "$WORKSPACE"/package_verify_full.sh 2>/dev/null || true
chmod +x "$WORKSPACE"/scripts/*.sh "$WORKSPACE"/tests/*.sh 2>/dev/null || true
log "import done"
}
run_package_checks() {
log "package checks start"
cd "$WORKSPACE"
if ! bash scripts/package_contract_check_v1r1c0.sh > "$LOG_DIR/package_contract_check_v1r1c0.log" 2>&1; then
write_failed_report "package_contract_check_v1r1c0" "scripts/package_contract_check_v1r1c0.sh failed; see $LOG_DIR/package_contract_check_v1r1c0.log"
exit 4
fi
if ! bash tests/run_v1r1c0_acceptance.sh > "$LOG_DIR/run_v1r1c0_acceptance.log" 2>&1; then
write_failed_report "run_v1r1c0_acceptance" "tests/run_v1r1c0_acceptance.sh failed; see $LOG_DIR/run_v1r1c0_acceptance.log"
exit 5
fi
if ! ./package_verify_full.sh > "$LOG_DIR/package_verify_full.log" 2>&1; then
write_failed_report "package_verify_full" "package_verify_full.sh failed; see $LOG_DIR/package_verify_full.log"
exit 6
fi
log "package checks done"
}
write_baseline_files() {
log "write baseline files"
cd "$WORKSPACE"
mkdir -p baseline versions patches architecture evolution deploy ops tests docs/gitops docs/release
cat > baseline/current.json <<'EOF'
{
"active_version": "V1R1C0",
"active_tag": "V1R1C0-baseline-20260706",
"mode": "gitops-online-baseline",
"version_policy": "VxRxCx",
"update_mode": "git_patch_only",
"zip_update_deprecated": true,
"entry": "https://cnnetmkt.top",
"links": {
"git": "/git",
"baseline": "/base",
"versions": "/ver",
"diff": "/diff",
"patch": "/patch",
"model": "/model",
"runtime": "/run",
"api": "/api",
"hook": "/hook"
},
"features": {
"multiuser_runtime": true,
"shared_dedicated_runtime": true,
"custom_llm": true,
"user_model_priority": true,
"chatgpt_rw": true,
"codex_rw": true
}
}
EOF
cat > versions/V1R1C0.json <<'EOF'
{
"version": "V1R1C0",
"tag": "V1R1C0-baseline-20260706",
"type": "baseline",
"name": "MultiUser GitOps Custom LLM Baseline",
"source": "AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip",
"update_mode": "git_patch_only",
"zip_update_mode": "deprecated_after_import"
}
EOF
cat > architecture/current.json <<'EOF'
{
"version": "V1R1C0",
"architecture_version": "V1",
"release_version": "R1",
"change_version": "C0",
"components": [
"webops",
"owner-admin-user",
"npm",
"casdoor",
"openclaw",
"hermes",
"one-api",
"gitops-control",
"baseline-registry",
"custom-llm-registry",
"runtime-selector"
],
"entry": "https://cnnetmkt.top",
"proxy": "npm",
"runtime_sync": "openclaw"
}
EOF
cat > docs/release/VxRxCx_RULES.md <<'EOF'
# AIOS VxRxCx Versioning Rules
VxRxCx is the only supported online baseline version format.
- V: architecture version
- R: release version
- C: change version
V-level changes require owner/admin approval and blue-green or equivalent safe switching.
R-level changes require canary or test-environment validation.
C-level changes require smoke test and automatic rollback on failure.
Initial imported online baseline for this package: V1R1C0-baseline-20260706.
EOF
cat > docs/gitops/CHATGPT_CODEX_ACCESS.md <<'EOF'
# ChatGPT / Codex GitOps Access
Entry: https://cnnetmkt.top
Short links: /git, /base, /ver, /diff, /patch, /model, /run, /api, /hook.
All writes must become Git commits. Fixes must use patch branches. Releases must use VxRxCx tags.
Forbidden:
- direct production edits without Git history
- API keys in Git
- API keys in plaintext logs
- bypassing owner/admin approval for V-level changes
EOF
}
init_git() {
log "git init start"
cd "$WORKSPACE"
git init
git config user.name "AIOS GitOps Bot"
git config user.email "gitops-bot@cnnetmkt.top"
if [ ! -f .gitignore ]; then
cat > .gitignore <<'EOF'
.env
*.secret
*.key
*.pem
*.log
__pycache__/
node_modules/
.venv/
.DS_Store
runtime/tmp/
runtime/cache/
logs/
EOF
fi
git add .
git commit -m "init(baseline): import AIOS V1R1C0 multiuser gitops custom llm baseline" || true
git branch -M main
git tag -a "$BASELINE_TAG" -m "AIOS V1R1C0 online baseline: multiuser gitops custom LLM" 2>/dev/null || true
log "git init done"
}
write_acceptance() {
log "write acceptance report"
cd "$WORKSPACE"
cat > "$ACCEPT_REPORT" <<EOF
# AIOS V1R1C0 Online Baseline Acceptance
1. server: $(hostname)
2. zip_path: $ZIP_PATH
3. npm_reused: PARTIAL_UNVERIFIED
4. webops_reused: YES_DETECTED
5. casdoor_reused: PARTIAL_UNVERIFIED
6. openclaw_reused: YES_DETECTED
7. hermes_reused: YES_DETECTED
8. one_api_reused: YES_DETECTED
9. git_service: LOCAL_GIT_READY_REMOTE_UI_PENDING
10. git_url: PENDING_GITEA_OR_EXISTING_GIT_SERVICE
11. short_links: /git,/base,/ver,/diff,/patch,/model,/run,/api,/hook
12. baseline_version: V1R1C0
13. baseline_tag: $BASELINE_TAG
14. custom_llm_api: PACKAGE_UAT_PASS_ONLINE_ROUTE_PENDING
15. model_priority: PACKAGE_UAT_PASS_ONLINE_ROUTE_PENDING
16. runtime_selector: PACKAGE_UAT_PASS_ONLINE_ROUTE_PENDING
17. gitops_patch: BASELINE_COMMIT_AND_TAG_READY
18. smoke_test: PACKAGE_CHECKS_PASS
19. known_issues:
- NPM custom locations were not modified by this script.
- Gitea/Web Git UI push was not completed by this script.
- Spark sub-agent quota was unavailable during orchestration.
20. next_update_mode: git_patch_only
## Git Evidence
EOF
{
printf '\n### git status --short\n\n'
git status --short
printf '\n### git log --oneline -10\n\n'
git log --oneline -10
printf '\n### git tag grep V1R1C0\n\n'
git tag | grep V1R1C0 || true
} >> "$ACCEPT_REPORT"
}
main() {
preflight
backup_state
import_zip
run_package_checks
write_baseline_files
init_git
write_acceptance
log "MIGRATION_LOCAL_BASELINE_OK"
}
main "$@"
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="/data/aios-gitops"
WORKSPACE="$ROOT/workspace"
LOG="$ROOT/logs/runtime-services-v1r1c0.log"
mkdir -p "$ROOT/logs" "$ROOT/runtime/secrets" "$WORKSPACE/deploy/systemd" "$WORKSPACE/deploy/gitea"
touch "$LOG"
log() {
printf '[%s] %s\n' "$(date -Is)" "$*" | tee -a "$LOG"
}
cd "$WORKSPACE"
TOKEN_FILE="$ROOT/runtime/secrets/gitops.tokens"
if [ ! -s "$TOKEN_FILE" ]; then
(openssl rand -hex 32 || python3 -c 'import secrets; print(secrets.token_hex(32))') > "$TOKEN_FILE"
chmod 600 "$TOKEN_FILE"
fi
cat > deploy/systemd/aios-gitops-model-api.service <<EOF
[Unit]
Description=AIOS V1R1C0 GitOps Model API
After=network.target
[Service]
Type=simple
User=aiman
Group=aiman
Environment=AIOS_GITOPS_ROOT=$ROOT
Environment=AIOS_GITOPS_WORKSPACE=$WORKSPACE
Environment=AIOS_GITOPS_DB=$ROOT/runtime/gitops_model.sqlite3
Environment=AIOS_GITOPS_TOKEN_FILE=$TOKEN_FILE
Environment=AIOS_GITOPS_HOST=127.0.0.1
Environment=AIOS_GITOPS_PORT=18890
ExecStart=/usr/bin/python3 $WORKSPACE/active-runtime/app/aios_gitops_model_api.py
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF
cat > deploy/gitea/docker-compose.yml <<'EOF'
services:
gitea:
image: gitea/gitea:1.22
container_name: aios-gitea
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__server__DOMAIN=cnnetmkt.top
- GITEA__server__ROOT_URL=https://cnnetmkt.top/git/
- GITEA__server__SERVE_FROM_SUB_PATH=true
- GITEA__server__HTTP_PORT=3000
- GITEA__server__SSH_DOMAIN=cnnetmkt.top
- GITEA__server__SSH_PORT=2222
- GITEA__service__DISABLE_REGISTRATION=true
- GITEA__webhook__ALLOWED_HOST_LIST=*
- GITEA__database__DB_TYPE=sqlite3
volumes:
- /data/aios-gitops/runtime/gitea:/data
ports:
- "127.0.0.1:3000:3000"
- "127.0.0.1:2222:22"
EOF
git add deploy/systemd/aios-gitops-model-api.service deploy/gitea/docker-compose.yml
git commit -m "chore(gitops): add V1R1C0 runtime API and Gitea deployment manifests" || true
log "install API systemd unit"
sudo cp deploy/systemd/aios-gitops-model-api.service /etc/systemd/system/aios-gitops-model-api.service
sudo systemctl daemon-reload
sudo systemctl enable --now aios-gitops-model-api.service
sleep 2
systemctl is-active aios-gitops-model-api.service | tee -a "$LOG"
curl -fsS http://127.0.0.1:18890/health | tee -a "$LOG"
log "start gitea"
mkdir -p "$ROOT/adapters/gitea"
cp deploy/gitea/docker-compose.yml "$ROOT/adapters/gitea/docker-compose.yml"
(cd "$ROOT/adapters/gitea" && docker compose up -d)
for i in $(seq 1 60); do
if curl -fsS http://127.0.0.1:3000/git/api/healthz >/dev/null 2>&1 || curl -fsS http://127.0.0.1:3000/git/ >/dev/null 2>&1; then
break
fi
sleep 2
done
curl -fsS http://127.0.0.1:3000/git/ >/dev/null || true
docker ps --format '{{.Names}} {{.Image}} {{.Status}} {{.Ports}}' | grep -E '^aios-gitea ' | tee -a "$LOG" || true
log "runtime manifests committed and services attempted"
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="/data/aios-gitops"
WORKSPACE="$ROOT/workspace"
cd "$WORKSPACE"
git add active-runtime/app/aios_gitops_model_api.py scripts/hermes_gitops_parallel_agents.py
git commit -m "fix(gitops): align baseline tag and secret scan" || true
python3 - <<'PY'
import datetime
import sqlite3
p = "/data/aios-gitops/runtime/gitops_model.sqlite3"
con = sqlite3.connect(p)
con.execute(
"UPDATE gitops_baseline SET active_version=?, active_tag=?, source_package=?, update_mode=?, updated_at=? WHERE id=?",
(
"V1R1C0",
"V1R1C0-baseline-20260706",
"AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip",
"git_patch_only",
datetime.datetime.utcnow().isoformat() + "Z",
"current",
),
)
con.commit()
con.close()
PY
sudo chown -R aiman:aiman "$ROOT/runtime" "$WORKSPACE" "$ROOT/logs" "$ROOT/artifacts"
sudo systemctl restart aios-gitops-model-api.service
sleep 2
curl -fsS http://127.0.0.1:18890/api/status
echo
python3 scripts/hermes_gitops_parallel_agents.py
+96
View File
@@ -0,0 +1,96 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="/data/aios-gitops"
WORKSPACE="$ROOT/workspace"
NGINX_SITE="/etc/nginx/sites-enabled/aios-user-portal.conf"
BACKUP_DIR="$ROOT/backups/nginx-gitops-$(date +%Y%m%d-%H%M%S)"
LOG="$ROOT/logs/nginx-gitops-routes.log"
mkdir -p "$BACKUP_DIR" "$ROOT/logs" "$WORKSPACE/deploy/nginx"
exec > >(tee -a "$LOG") 2>&1
cd "$WORKSPACE"
cat > deploy/nginx/aios-gitops-locations.conf <<'EOF'
# BEGIN AIOS V1R1C0 GitOps short links
location = /git { return 302 /git/; }
location /git/ {
proxy_pass http://127.0.0.1:3000/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /git;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
}
location = /api { return 302 /api/; }
location /api/ {
proxy_pass http://127.0.0.1:18890/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location = /base { proxy_pass http://127.0.0.1:18890/base; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
location = /ver { proxy_pass http://127.0.0.1:18890/ver; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
location = /diff { proxy_pass http://127.0.0.1:18890/diff; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
location = /patch { proxy_pass http://127.0.0.1:18890/patch; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
location = /model { proxy_pass http://127.0.0.1:18890/model; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
location = /run { proxy_pass http://127.0.0.1:18890/run; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
location = /hook { proxy_pass http://127.0.0.1:18890/hook; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
location /hook/ {
proxy_pass http://127.0.0.1:18890/hook/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# END AIOS V1R1C0 GitOps short links
EOF
git add deploy/nginx/aios-gitops-locations.conf active-runtime/app/aios_gitops_model_api.py
git commit -m "feat(gitops): add nginx short links and webhook endpoint" || true
echo "== backup nginx site =="
sudo cp -a "$NGINX_SITE" "$BACKUP_DIR/aios-user-portal.conf"
echo "== insert locations =="
python3 - <<'PY'
from pathlib import Path
site = Path("/etc/nginx/sites-enabled/aios-user-portal.conf")
snippet = Path("/data/aios-gitops/workspace/deploy/nginx/aios-gitops-locations.conf").read_text()
text = site.read_text()
start = " # BEGIN AIOS V1R1C0 GitOps short links"
end = " # END AIOS V1R1C0 GitOps short links"
if start in text:
before = text.split(start)[0]
after = text.split(end, 1)[1]
text = before + snippet + after
else:
marker = " location / {\n"
if marker not in text:
raise SystemExit("location marker not found")
text = text.replace(marker, snippet + "\n" + marker, 1)
Path("/tmp/aios-user-portal.conf.gitops").write_text(text)
PY
sudo cp /tmp/aios-user-portal.conf.gitops "$NGINX_SITE"
echo "== nginx test and reload =="
sudo nginx -t
sudo systemctl reload nginx
echo "== local route checks =="
for path in /git/ /base /ver /model /run /hook /api/status; do
echo "== ${path} =="
curl -k -sS -I --resolve cnnetmkt.top:443:127.0.0.1 "https://cnnetmkt.top${path}" | sed -n '1,12p' || true
done
echo "NGINX_GITOPS_ROUTES_OK backup=$BACKUP_DIR"
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -euo pipefail
for path in /git/ /base /ver /model /run /hook /api/status; do
echo "== ${path} =="
curl -k -sS --max-time 10 --resolve cnnetmkt.top:443:127.0.0.1 "https://cnnetmkt.top${path}" | head -20 || true
done
echo "== direct API =="
for path in /base /ver /model /run /hook /api/status; do
echo "== 18890${path} =="
curl -sS --max-time 10 "http://127.0.0.1:18890${path}" | head -10 || true
done
+221
View File
@@ -0,0 +1,221 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="/data/aios-gitops"
WORKSPACE="$ROOT/workspace"
ARTIFACT="$ROOT/artifacts/AIOS_V1R1C0_ONLINE_BASELINE_ACCEPTANCE.md"
REPORT_IN_REPO="$WORKSPACE/docs/release/AIOS_V1R1C0_ONLINE_BASELINE_ACCEPTANCE.md"
EVIDENCE="$ROOT/artifacts/AIOS_V1R1C0_FINAL_EVIDENCE.txt"
VERSION="V1R1C0"
TAG="V1R1C0-baseline-20260706"
SOURCE="AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip"
GIT_URL="https://cnnetmkt.top/git/aios/aios-v23.git"
mkdir -p "$ROOT/artifacts" "$ROOT/logs" "$WORKSPACE/docs/release"
python3 - <<'PY'
import json
import sqlite3
from datetime import datetime, timezone
from pathlib import Path
root = Path("/data/aios-gitops")
workspace = root / "workspace"
db = root / "runtime" / "gitops_model.sqlite3"
version = "V1R1C0"
tag = "V1R1C0-baseline-20260706"
source = "AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip"
entry = "https://cnnetmkt.top"
git_url = "https://cnnetmkt.top/git/aios/aios-v23.git"
short_links = ["/git", "/base", "/ver", "/diff", "/patch", "/model", "/run", "/api", "/hook"]
current_path = workspace / "baseline" / "current.json"
current = {}
if current_path.exists():
current = json.loads(current_path.read_text(encoding="utf-8"))
current.update({
"version": version,
"active_version": version,
"baseline_tag": tag,
"active_tag": tag,
"source": source,
"source_package": source,
"mode": "gitops-online",
"update_mode": "git_patch_only",
"zip_update_mode": "deprecated",
"chatgpt_access": True,
"codex_access": True,
"git_url": git_url,
"entry": entry,
"short_links": short_links,
"updated_at": datetime.now(timezone.utc).isoformat(),
})
current_path.write_text(json.dumps(current, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
version_path = workspace / "versions" / "V1R1C0.json"
version_doc = {}
if version_path.exists():
version_doc = json.loads(version_path.read_text(encoding="utf-8"))
version_doc.update({
"version": version,
"tag": tag,
"baseline_tag": tag,
"source": source,
"update_mode": "git_patch_only",
"zip_update_mode": "deprecated",
"git_url": git_url,
"updated_at": datetime.now(timezone.utc).isoformat(),
})
version_path.write_text(json.dumps(version_doc, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
if db.exists():
con = sqlite3.connect(db)
try:
con.execute(
"UPDATE gitops_baseline SET active_version=?, active_tag=?, source_package=?, entry=?, update_mode=?, status=?, updated_at=? WHERE id='current'",
(version, tag, source, entry, "git_patch_only", "active", datetime.now(timezone.utc).isoformat()),
)
con.execute(
"UPDATE gitops_versions SET tag=?, status=? WHERE version=?",
(tag, "ready", version),
)
con.commit()
finally:
con.close()
PY
cd "$WORKSPACE"
{
echo "== services =="
systemctl is-active aios-gitops-model-api aios-gitea aios-hermes-router aios-hermes-executor openclaw-gateway nginx || true
echo
echo "== gitea =="
curl -fsS http://127.0.0.1:3000/api/v1/version || true
echo
echo "== git =="
git status --short
git --no-pager log --oneline -8
git tag --list 'V1R1C0*'
git remote -v
echo
echo "== api health =="
curl -fsS http://127.0.0.1:18890/health
echo
curl -fsS http://127.0.0.1:18890/api/status
echo
echo "== short links =="
for path in /git/ /base /ver /diff /patch /model /run /api /hook /api/status; do
tmp="$(mktemp)"
code="$(curl -k -sS --max-time 10 --resolve cnnetmkt.top:443:127.0.0.1 -o "$tmp" -w "%{http_code}" "https://cnnetmkt.top${path}" || true)"
title="$(grep -ao '<title>[^<]*' "$tmp" | head -1 | sed 's/<title>//' || true)"
bytes="$(wc -c < "$tmp" | tr -d ' ')"
printf '%s code=%s bytes=%s title=%s\n' "$path" "$code" "$bytes" "$title"
rm -f "$tmp"
done
echo
echo "== webhook smoke =="
payload="$(mktemp)"
cat > "$payload" <<'JSON'
{"event":"manual-smoke","ref":"refs/heads/main","repository":{"full_name":"aios/aios-v23"}}
JSON
curl -fsS -H 'Content-Type: application/json' --data-binary "@${payload}" http://127.0.0.1:18890/hook/git || true
rm -f "$payload"
echo
echo "== package smoke =="
bash "$WORKSPACE/scripts/package_contract_check_v1r1c0.sh" || true
echo
echo "== hermes =="
curl -fsS http://127.0.0.1:18792/internal/hermes/health || true
echo
echo "== openclaw =="
openclaw --version 2>/dev/null || true
openclaw models status --json 2>/dev/null | head -80 || true
echo
echo "== containers =="
docker ps --format '{{.Names}} {{.Image}} {{.Ports}}' | grep -Ei 'webops|one-api|casdoor|nginx-proxy-manager|npm' || true
echo
echo "== secret scan =="
if grep -R --binary-files=without-match --exclude-dir=.git -E 'sk-[A-Za-z0-9_-]{20,}|AIza[0-9A-Za-z_-]{20,}|xox[baprs]-[0-9A-Za-z-]{20,}' -n "$WORKSPACE" "$ROOT/logs" "$ROOT/artifacts" 2>/dev/null | head -20; then
echo "SECRET_SCAN=FAILED"
else
echo "SECRET_SCAN=OK"
fi
} | tee "$EVIDENCE"
cat > "$ARTIFACT" <<EOF_REPORT
# AIOS V1R1C0 Online Baseline Acceptance
AIOS_V1R1C0_ONLINE_BASELINE_STATUS=PARTIAL
DOMAIN=https://cnnetmkt.top
SHORT_LINKS=/git,/base,/ver,/diff,/patch,/model,/run,/api,/hook
PROXY=NGINX_TEMP (NPM_NOT_RUNNING)
GIT_URL=$GIT_URL
BASELINE_VERSION=$VERSION
BASELINE_TAG=$TAG
WORKSPACE=$WORKSPACE
WEBOPS_REUSED=YES
CASDOOR_REUSED=PARTIAL
OPENCLAW_REUSED=PARTIAL
HERMES_REUSED=YES
ONE_API_REUSED=YES
GITEA_REUSED=NEW
CUSTOM_LLM_STATUS=OK
MODEL_PRIORITY_STATUS=OK
RUNTIME_SELECTOR_STATUS=OK
ACCEPTANCE_REPORT=$ARTIFACT
KNOWN_ISSUES=NPM is not running on this host, so system nginx currently serves the short links; OpenClaw gateway is active but native openclaw agent execution still needs gateway/provider credentials; host-side DNS resolution for cnnetmkt.top is unreliable, so local validation used --resolve to 127.0.0.1; Docker Hub pull for Gitea was blocked by the existing Docker proxy path and was replaced with official Gitea binary deployment.
NEXT_UPDATE_MODE=git_patch_only
ZIP_UPDATE_MODE=deprecated
## Evidence
- Imported package: /data/aios-gitops/imports/$SOURCE
- Package SHA256: dbee5d45aab02aab33e862bb9beb6115b3b43137e0fb5e00c98448ac1ecfd0f9
- Git workspace: $WORKSPACE
- Baseline branch: main
- Baseline tag: $TAG
- Git remote: $GIT_URL
- Gitea internal version: 1.22.6
- API service: aios-gitops-model-api.service on 127.0.0.1:18890
- Gitea service: aios-gitea.service on 127.0.0.1:3000
- Hermes executor health: ok
- One API reused at: 127.0.0.1:13000
- WebOps reused container: aios-webops-server-hw-webops-1
- Parallel server agents: git_service_agent, entry_proxy_agent, gitops_api_uat_agent, acceptance_report_agent
- Parallel agent report: /data/aios-gitops/artifacts/AIOS_V1R1C0_PARALLEL_AGENT_STATUS.json
- Final evidence log: $EVIDENCE
## GitOps Rules
- ZIP update mode is deprecated after initial import.
- Future updates must be git branch + commit + push + webhook.
- Patches are represented as git branches and are reviewable by diff.
- ChatGPT/Codex write path is /api/git-control-compatible endpoints exposed by the GitOps API.
EOF_REPORT
cp "$ARTIFACT" "$REPORT_IN_REPO"
git add baseline/current.json versions/V1R1C0.json docs/release/AIOS_V1R1C0_ONLINE_BASELINE_ACCEPTANCE.md
git commit -m "docs(gitops): finalize V1R1C0 online baseline acceptance" || true
admin_user="aios"
admin_pass_file="$ROOT/runtime/secrets/gitea-admin-password"
if [ -s "$admin_pass_file" ]; then
tmp_home="$(mktemp -d)"
chmod 700 "$tmp_home"
{
echo "machine 127.0.0.1"
echo "login $admin_user"
echo "password $(cat "$admin_pass_file")"
} > "$tmp_home/.netrc"
chmod 600 "$tmp_home/.netrc"
HOME="$tmp_home" git push http://127.0.0.1:3000/aios/aios-v23.git main
HOME="$tmp_home" git push http://127.0.0.1:3000/aios/aios-v23.git --tags
rm -rf "$tmp_home"
fi
git remote remove origin 2>/dev/null || true
git remote add origin "$GIT_URL"
git status --short
echo "FINALIZE_V1R1C0_GITOPS_ACCEPTANCE_DONE"
+53
View File
@@ -0,0 +1,53 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="/data/aios-gitops"
WORKSPACE="$ROOT/workspace"
GITEA_BIN="$ROOT/runtime/bin/gitea"
GITEA_HOME="$ROOT/runtime/gitea-bin"
SECRETS="$ROOT/runtime/secrets"
LOG="$ROOT/logs/gitea-repo-push-fix.log"
mkdir -p "$ROOT/logs"
exec > >(tee -a "$LOG") 2>&1
admin_user="aios"
admin_pass="$(cat "$SECRETS/gitea-admin-password")"
echo "== endpoint probe =="
for path in / /git/ /api/v1/version /git/api/v1/version /user/login /git/user/login; do
echo "== ${path} =="
curl -sS -i --max-time 8 "http://127.0.0.1:3000${path}" 2>&1 | sed -n '1,18p'
done
echo "== ensure admin user =="
"$GITEA_BIN" admin user create \
--config "$GITEA_HOME/custom/conf/app.ini" \
--username "$admin_user" \
--password "$admin_pass" \
--email "gitops-bot@cnnetmkt.top" \
--admin \
--must-change-password=false 2>/dev/null || true
echo "== create repo by internal API =="
if ! curl -fsS -u "$admin_user:$admin_pass" "http://127.0.0.1:3000/api/v1/repos/$admin_user/aios-v23" >/dev/null 2>&1; then
curl -fsS -u "$admin_user:$admin_pass" \
-H "Content-Type: application/json" \
-d '{"name":"aios-v23","description":"AIOS V1R1C0 online GitOps baseline","private":false,"auto_init":false,"default_branch":"main"}' \
"http://127.0.0.1:3000/api/v1/user/repos" >/dev/null
fi
curl -fsS -u "$admin_user:$admin_pass" "http://127.0.0.1:3000/api/v1/repos/$admin_user/aios-v23" | python3 -m json.tool | sed -n '1,80p'
echo "== push main and tags =="
cd "$WORKSPACE"
push_url="http://${admin_user}:${admin_pass}@127.0.0.1:3000/${admin_user}/aios-v23.git"
git push "$push_url" main
git push "$push_url" --tags
git remote remove origin 2>/dev/null || true
git remote add origin "https://cnnetmkt.top/git/${admin_user}/aios-v23.git"
echo "== verify repo page =="
curl -fsS "http://127.0.0.1:3000/${admin_user}/aios-v23" | grep -E "aios-v23|AIOS|V1R1C0" | head -30 || true
git remote -v
git log --oneline -8
git status --short
echo "GITEA_REPO_PUSH_OK"
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="/data/aios-gitops"
WORKSPACE="$ROOT/workspace"
LOG="$ROOT/logs/gitops-api-owner-fix-uat.log"
mkdir -p "$ROOT/logs"
exec > >(tee -a "$LOG") 2>&1
echo "== fix ownership =="
sudo chown -R aiman:aiman "$ROOT/runtime" "$WORKSPACE" "$ROOT/logs" "$ROOT/artifacts"
echo "== commit sanitized runner =="
cd "$WORKSPACE"
git add scripts/hermes_gitops_parallel_agents.py
git commit -m "fix(gitops): sanitize parallel agent UAT secret handling" || true
echo "== restart API =="
sudo systemctl restart aios-gitops-model-api.service
sleep 3
systemctl status aios-gitops-model-api.service --no-pager | sed -n '1,100p'
curl -fsS http://127.0.0.1:18890/health
echo
curl -fsS http://127.0.0.1:18890/api/status
echo
echo "== API UAT =="
TOKEN="$(head -1 "$ROOT/runtime/secrets/gitops.tokens")"
curl -fsS \
-H "Authorization: Bearer $TOKEN" \
-H 'X-AIOS-User: agent-uat' \
-H 'X-AIOS-Role: owner' \
-H 'Content-Type: application/json' \
-d '{"username":"agent-uat","role":"owner","tier":"ultra"}' \
http://127.0.0.1:18890/api/runtime/select
echo
curl -fsS \
-H "Authorization: Bearer $TOKEN" \
-H 'X-AIOS-User: agent-uat' \
-H 'X-AIOS-Role: owner' \
-H 'Content-Type: application/json' \
-d '{"provider_name":"agent-local-openai-compatible","base_url":"http://127.0.0.1:13000/v1","model_name":"agent-test-model","display_name":"Agent Test Model","priority":10,"api_key_secret_ref":"secret://llm/agent-uat/pre-provisioned-test"}' \
http://127.0.0.1:18890/api/model/custom/add
echo
curl -fsS \
-H "Authorization: Bearer $TOKEN" \
-H 'X-AIOS-User: agent-uat' \
-H 'X-AIOS-Role: owner' \
-H 'Content-Type: application/json' \
-d '{"username":"agent-uat"}' \
http://127.0.0.1:18890/api/model/route/resolve
echo
echo "== secret scan =="
if grep -R 'redacted-test-key\|sk-[A-Za-z0-9]' -n "$WORKSPACE" "$ROOT/logs" 2>/dev/null; then
echo "SECRET_SCAN_FAILED"
exit 2
fi
echo "SECRET_SCAN_OK"
echo "== git status =="
git status --short
git log --oneline -8
+174
View File
@@ -0,0 +1,174 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="/data/aios-gitops"
WORKSPACE="$ROOT/workspace"
GITEA_HOME="$ROOT/runtime/gitea-bin"
GITEA_BIN="$ROOT/runtime/bin/gitea"
GITEA_VERSION="1.22.6"
GITEA_URL="https://dl.gitea.com/gitea/${GITEA_VERSION}/gitea-${GITEA_VERSION}-linux-amd64"
SECRETS="$ROOT/runtime/secrets"
LOG="$ROOT/logs/gitea-binary-install.log"
mkdir -p "$ROOT/logs" "$SECRETS" "$ROOT/runtime/bin" "$GITEA_HOME/custom/conf" "$GITEA_HOME/data" "$GITEA_HOME/log" "$WORKSPACE/deploy/gitea-binary"
exec > >(tee -a "$LOG") 2>&1
cd "$WORKSPACE"
echo "== write tracked deployment manifests =="
cat > deploy/gitea-binary/app.ini.template <<'EOF'
APP_NAME = AIOS GitOps
RUN_USER = aiman
WORK_PATH = /data/aios-gitops/runtime/gitea-bin
[server]
PROTOCOL = http
HTTP_ADDR = 127.0.0.1
HTTP_PORT = 3000
DOMAIN = cnnetmkt.top
ROOT_URL = https://cnnetmkt.top/git/
SERVE_FROM_SUB_PATH = true
DISABLE_SSH = true
OFFLINE_MODE = false
[database]
DB_TYPE = sqlite3
PATH = /data/aios-gitops/runtime/gitea-bin/data/gitea.db
[repository]
ROOT = /data/aios-gitops/runtime/gitea-bin/data/repositories
DEFAULT_BRANCH = main
[security]
INSTALL_LOCK = true
SECRET_KEY = __SECRET_KEY__
INTERNAL_TOKEN = __INTERNAL_TOKEN__
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
[webhook]
ALLOWED_HOST_LIST = *
[log]
MODE = console
LEVEL = Info
ROOT_PATH = /data/aios-gitops/runtime/gitea-bin/log
EOF
cat > deploy/gitea-binary/aios-gitea.service <<EOF
[Unit]
Description=AIOS GitOps Gitea
After=network.target
[Service]
Type=simple
User=aiman
Group=aiman
WorkingDirectory=$GITEA_HOME
ExecStart=$GITEA_BIN web --config $GITEA_HOME/custom/conf/app.ini
Restart=always
RestartSec=3
Environment=USER=aiman
Environment=HOME=/home/aiman
[Install]
WantedBy=multi-user.target
EOF
git add deploy/gitea-binary/app.ini.template deploy/gitea-binary/aios-gitea.service
git commit -m "chore(gitops): add binary Gitea deployment manifests" || true
echo "== download gitea binary =="
if [ ! -x "$GITEA_BIN" ]; then
tmp="$GITEA_BIN.tmp"
curl -fL --retry 3 --connect-timeout 20 -o "$tmp" "$GITEA_URL"
chmod 755 "$tmp"
mv "$tmp" "$GITEA_BIN"
fi
"$GITEA_BIN" --version
echo "== render runtime app.ini =="
secret_key_file="$SECRETS/gitea-secret-key"
internal_token_file="$SECRETS/gitea-internal-token"
admin_pass_file="$SECRETS/gitea-admin-password"
api_token_file="$SECRETS/gitea-api-token"
for f in "$secret_key_file" "$internal_token_file" "$admin_pass_file"; do
if [ ! -s "$f" ]; then
openssl rand -hex 32 > "$f"
chmod 600 "$f"
fi
done
sed \
-e "s#__SECRET_KEY__#$(cat "$secret_key_file")#g" \
-e "s#__INTERNAL_TOKEN__#$(cat "$internal_token_file")#g" \
deploy/gitea-binary/app.ini.template > "$GITEA_HOME/custom/conf/app.ini"
chmod 600 "$GITEA_HOME/custom/conf/app.ini"
sudo chown -R aiman:aiman "$ROOT/runtime" "$WORKSPACE/deploy/gitea-binary"
echo "== install systemd service =="
sudo cp deploy/gitea-binary/aios-gitea.service /etc/systemd/system/aios-gitea.service
sudo systemctl daemon-reload
sudo systemctl enable --now aios-gitea.service
echo "== wait gitea =="
for i in $(seq 1 90); do
if curl -fsS http://127.0.0.1:3000/git/api/healthz >/dev/null 2>&1 || curl -fsS http://127.0.0.1:3000/git/ >/dev/null 2>&1; then
break
fi
sleep 2
done
systemctl is-active aios-gitea.service
curl -fsS http://127.0.0.1:3000/git/api/healthz || true
echo
echo "== create admin user and repo =="
admin_user="aios"
admin_email="gitops-bot@cnnetmkt.top"
admin_pass="$(cat "$admin_pass_file")"
"$GITEA_BIN" admin user create \
--config "$GITEA_HOME/custom/conf/app.ini" \
--username "$admin_user" \
--password "$admin_pass" \
--email "$admin_email" \
--admin \
--must-change-password=false 2>/dev/null || true
if [ ! -s "$api_token_file" ]; then
"$GITEA_BIN" admin user generate-access-token \
--config "$GITEA_HOME/custom/conf/app.ini" \
--username "$admin_user" \
--token-name aios-gitops-push \
--scopes write:repository,read:repository,write:user,read:user \
| awk '/Access token was successfully created/ {print $NF}' > "$api_token_file.tmp" || true
if [ -s "$api_token_file.tmp" ]; then
mv "$api_token_file.tmp" "$api_token_file"
chmod 600 "$api_token_file"
else
rm -f "$api_token_file.tmp"
fi
fi
repo_api="http://127.0.0.1:3000/git/api/v1/user/repos"
if ! curl -fsS -u "$admin_user:$admin_pass" "http://127.0.0.1:3000/git/api/v1/repos/$admin_user/aios-v23" >/dev/null 2>&1; then
curl -fsS -u "$admin_user:$admin_pass" \
-H "Content-Type: application/json" \
-d '{"name":"aios-v23","description":"AIOS V1R1C0 online GitOps baseline","private":false,"auto_init":false,"default_branch":"main"}' \
"$repo_api" >/dev/null
fi
echo "== push repository =="
push_url="http://${admin_user}:${admin_pass}@127.0.0.1:3000/git/${admin_user}/aios-v23.git"
git push "$push_url" main
git push "$push_url" --tags
git remote remove origin 2>/dev/null || true
git remote add origin "https://cnnetmkt.top/git/${admin_user}/aios-v23.git"
echo "== verify gitea repo =="
curl -fsS "http://127.0.0.1:3000/git/${admin_user}/aios-v23" | grep -E "aios-v23|AIOS" | head -20 || true
git status --short
git log --oneline -8
git remote -v
echo "GITEA_BINARY_INSTALL_OK version=$GITEA_VERSION url=https://cnnetmkt.top/git/${admin_user}/aios-v23"
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
for v in 1.22.6 1.22.5 1.22.4 1.22.3 1.22.2 1.22.1 1.22.0; do
url="https://dl.gitea.com/gitea/${v}/gitea-${v}-linux-amd64"
echo "== ${v} ${url} =="
curl -I --max-time 20 "$url" 2>&1 | sed -n '1,16p'
done
+1 -1
View File
@@ -8,5 +8,5 @@
"zip_update_mode": "deprecated",
"baseline_tag": "V1R1C0-baseline-20260706",
"git_url": "https://cnnetmkt.top/git/aios/aios-v23.git",
"updated_at": "2026-07-06T07:13:43.274366+00:00"
"updated_at": "2026-07-06T07:16:01.842715+00:00"
}