Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68eb88cf04 | ||
|
|
3218b89a2c | ||
|
|
6ac62c265b | ||
|
|
2322120f39 | ||
|
|
c27b91c708 |
@@ -0,0 +1,48 @@
|
||||
cmd_id: CMD-20260710-memory-index-rebuild
|
||||
operation: memory.index.rebuild
|
||||
risk: medium
|
||||
permission: OWNER_NON_DANGEROUS_ALL
|
||||
status: pending_owner_gate
|
||||
reason: Memory search is disabled because existing embedding index metadata does not match the current embedding provider configuration.
|
||||
requested_by: codex-chartgpt-bridge
|
||||
requested_at: "2026-07-10T08:00:00+08:00"
|
||||
command_key: openclaw.memory.index.force
|
||||
args:
|
||||
force: true
|
||||
safety:
|
||||
destructive: false
|
||||
arbitrary_shell: false
|
||||
credential_mutation: false
|
||||
provider_mutation: false
|
||||
external_network_write: false
|
||||
production_data_delete: false
|
||||
baseline_or_tag_mutation: false
|
||||
main_branch_direct_write: false
|
||||
owner_gate:
|
||||
required: true
|
||||
approval_model: protected_branch_merge_or_signed_owner_commit
|
||||
approved_by: null
|
||||
approved_at: null
|
||||
approval_commit: null
|
||||
execution:
|
||||
runner: owner-maintenance-runner
|
||||
lock_key: memory-index-rebuild
|
||||
timeout_seconds: 1800
|
||||
executed_by: null
|
||||
executed_at: null
|
||||
exit_code: null
|
||||
acceptance:
|
||||
commands:
|
||||
- openclaw memory search "V1R4C3"
|
||||
- openclaw memory search "Gitea Branch Sync"
|
||||
- openclaw memory search "Autonomous Controller"
|
||||
expected:
|
||||
- no_embedding_metadata_mismatch
|
||||
- memory_search_returns_results
|
||||
- memory_index_uses_current_embedding_provider
|
||||
success_signals:
|
||||
- AIOS_OWNER_MAINTENANCE_MEMORY_INDEX_REBUILT
|
||||
- AIOS_MEMORY_SEARCH_RESTORED
|
||||
rollback:
|
||||
destructive: false
|
||||
strategy: rebuild_previous_index_if_snapshot_exists
|
||||
@@ -0,0 +1,49 @@
|
||||
# Owner Maintenance Gate
|
||||
|
||||
This mechanism allows owner-approved non-dangerous maintenance actions without giving agents arbitrary host CLI access.
|
||||
|
||||
## Permission tiers
|
||||
|
||||
- READ_ONLY: status, health, baseline, versions, search inspection.
|
||||
- AUTO_PATCH: branch creation, repo file changes, patch commits, test/report artifacts.
|
||||
- OWNER_NON_DANGEROUS_ALL: owner may approve all non-destructive allowlisted maintenance command_keys.
|
||||
- OWNER_HIGH_RISK: main merge, baseline promotion, tag creation, credential/provider mutation, destructive cleanup, production restart, SSH/firewall changes.
|
||||
|
||||
## Execution rule
|
||||
|
||||
Agents can create requests. The runner can only execute fixed allowlist mappings:
|
||||
|
||||
```text
|
||||
command_key: openclaw.memory.index.force
|
||||
argv: /usr/local/bin/openclaw memory index --force
|
||||
```
|
||||
|
||||
The runner rejects arbitrary shell strings such as `bash -c`, `sh -c`, `curl | bash`, or recursive destructive commands.
|
||||
|
||||
## Owner gate
|
||||
|
||||
A request becomes executable only after protected-branch merge or signed owner commit fills:
|
||||
|
||||
```yaml
|
||||
owner_gate:
|
||||
approved_by: <owner>
|
||||
approved_at: <timestamp>
|
||||
approval_commit: <signed-owner-commit-sha>
|
||||
```
|
||||
|
||||
## Memory index rebuild flow
|
||||
|
||||
1. Detect embedding metadata mismatch.
|
||||
2. Create `commands/owner-requests/CMD-20260710-memory-index-rebuild.yaml`.
|
||||
3. Owner approves through GitOps owner gate.
|
||||
4. `runtime/owner_maintenance/allowlist_runner.py` validates safety metadata.
|
||||
5. Runner executes the fixed command vector.
|
||||
6. Runner records exit code and stdout/stderr hashes.
|
||||
7. Acceptance checks verify memory search works again.
|
||||
|
||||
Expected signals:
|
||||
|
||||
```text
|
||||
AIOS_OWNER_MAINTENANCE_MEMORY_INDEX_REBUILT
|
||||
AIOS_MEMORY_SEARCH_RESTORED
|
||||
```
|
||||
@@ -1,212 +0,0 @@
|
||||
# V1R4C5 Acceptance Evidence
|
||||
|
||||
Date: 2026-07-11
|
||||
|
||||
Status: release candidate evidence in progress
|
||||
|
||||
Current active baseline: V1R4C3
|
||||
|
||||
V1R4C5 has not been promoted yet.
|
||||
|
||||
## Owner Decision
|
||||
|
||||
Owner approved continued V1R4C5 work under the following constraints:
|
||||
|
||||
```text
|
||||
允许无 force-push 的分支 reconcile
|
||||
memory search 保持关闭
|
||||
先完成 SR-01/SR-02/数据隔离验收
|
||||
再进入 merge/deploy/tag owner gate
|
||||
```
|
||||
|
||||
## Scope
|
||||
|
||||
V1R4C5 release candidate scope:
|
||||
|
||||
1. SR-01 Gitea reliability and branch consistency guardrails.
|
||||
2. SR-02 watcher/stuck command cleanup.
|
||||
3. User data isolation redline and enforcement gates.
|
||||
4. SR-04 admin workbench read-only visibility preparation only.
|
||||
|
||||
Explicitly excluded from V1R4C5 activation:
|
||||
|
||||
- memory search activation;
|
||||
- full SR-04 portal production rollout;
|
||||
- bulk merge of old test/smoke/auth branches;
|
||||
- force push reconciliation;
|
||||
- Gitea DB mutation without owner/admin approval.
|
||||
|
||||
## Runtime Acceptance Evidence
|
||||
|
||||
### Runtime status
|
||||
|
||||
Observed:
|
||||
|
||||
```json
|
||||
{
|
||||
"service": "aios-gitops-model-api",
|
||||
"status": "active",
|
||||
"workspace_branch": "patch/v1r4c5-runtime-acceptance-clean-20260711-01"
|
||||
}
|
||||
```
|
||||
|
||||
### Baseline
|
||||
|
||||
Observed:
|
||||
|
||||
```json
|
||||
{
|
||||
"current_baseline": "V1R4C3",
|
||||
"previous_baseline": "V1R3C1",
|
||||
"promoted_by": "openclaw"
|
||||
}
|
||||
```
|
||||
|
||||
### Clean createBranch acceptance
|
||||
|
||||
Branch:
|
||||
|
||||
```text
|
||||
test/v1r4c5-runtime-acceptance-clean-20260711-01
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```text
|
||||
status: ok
|
||||
commit: 6ae7058
|
||||
sync: synced
|
||||
```
|
||||
|
||||
### Clean createPatch acceptance
|
||||
|
||||
Patch:
|
||||
|
||||
```text
|
||||
patch/v1r4c5-runtime-acceptance-clean-20260711-01
|
||||
```
|
||||
|
||||
Patch id:
|
||||
|
||||
```text
|
||||
patch-1783706123789-f5ca8b69
|
||||
```
|
||||
|
||||
Commit:
|
||||
|
||||
```text
|
||||
ba0391e
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```text
|
||||
synced
|
||||
```
|
||||
|
||||
## SR-01 Evidence
|
||||
|
||||
Known accepted evidence:
|
||||
|
||||
- Gitea branch consistency sentinel deployed.
|
||||
- Sentinel reports:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"unhealthy_checks": []
|
||||
}
|
||||
```
|
||||
|
||||
- systemd timer runs every 5 minutes.
|
||||
- service runs with:
|
||||
|
||||
```text
|
||||
--emit-safe-mode --json
|
||||
```
|
||||
|
||||
- broken symlink issue resolved by replacing the external reliability symlink with workspace-local files.
|
||||
|
||||
Required before final promotion:
|
||||
|
||||
- confirm latest sentinel report remains healthy after acceptance writes.
|
||||
|
||||
## SR-02 Evidence
|
||||
|
||||
Known accepted evidence:
|
||||
|
||||
```text
|
||||
11 / 11 tests pass
|
||||
```
|
||||
|
||||
Fix summary:
|
||||
|
||||
- stuck command detection reads parsed timestamps through `data.get('ts', 0)`;
|
||||
- `.md` fixture mtime is aligned with stored stuck timestamp via `os.utime(path, (ts, ts))`;
|
||||
- behavior is consistent across `.json` and `.md` state formats.
|
||||
|
||||
Required before final promotion:
|
||||
|
||||
- re-run SR-02 tests on the final integration candidate.
|
||||
|
||||
## User Data Isolation Evidence
|
||||
|
||||
Implemented controls:
|
||||
|
||||
- user data isolation redline;
|
||||
- memory scope guard;
|
||||
- provider gate;
|
||||
- activation gate;
|
||||
- audit service/timer;
|
||||
- CI acceptance scripts;
|
||||
- memory search activation check.
|
||||
|
||||
Required safety state:
|
||||
|
||||
```text
|
||||
AIOS_MEMORY_ENABLED=false
|
||||
```
|
||||
|
||||
Required before memory/search activation:
|
||||
|
||||
- isolation audit healthy;
|
||||
- no denied records;
|
||||
- no invalid records;
|
||||
- provider filters by scope before ranking;
|
||||
- provenance required;
|
||||
- global index disabled;
|
||||
- activation gate returns allowed;
|
||||
- explicit owner approval.
|
||||
|
||||
V1R4C5 does not approve memory search activation.
|
||||
|
||||
## SR-04 Admin Workbench Evidence
|
||||
|
||||
Current user-visible gap is confirmed:
|
||||
|
||||
- administrator cannot yet see task progress;
|
||||
- administrator cannot yet see flow/process diagrams;
|
||||
- SR-04 remains activation-ready but gated.
|
||||
|
||||
V1R4C5 scope allows only read-only visibility preparation and acceptance design, not full production rollout.
|
||||
|
||||
Required before SR-04 deployment:
|
||||
|
||||
- SR-01 green;
|
||||
- SR-02 green;
|
||||
- user data isolation gate accepted;
|
||||
- admin RBAC read-only check green.
|
||||
|
||||
## Remaining Required Gates Before Promotion
|
||||
|
||||
- [ ] Latest Gitea sentinel report remains healthy.
|
||||
- [ ] SR-02 watcher tests pass on final candidate.
|
||||
- [ ] User data isolation acceptance passes.
|
||||
- [ ] Admin workbench read-only RBAC acceptance passes or remains explicitly deferred.
|
||||
- [ ] No force-push was used.
|
||||
- [ ] Memory search remains disabled.
|
||||
- [ ] Owner approves merge/deploy/tag/promotion.
|
||||
|
||||
## Promotion Rule
|
||||
|
||||
V1R4C5 may not be promoted until all required gates are green or explicitly deferred with owner approval.
|
||||
@@ -1,54 +0,0 @@
|
||||
# V1R4C5 Final Owner Approval
|
||||
|
||||
Date: 2026-07-11
|
||||
|
||||
Status: approved for final promotion
|
||||
|
||||
## Owner Decision
|
||||
|
||||
Owner approved final V1R4C5 promotion.
|
||||
|
||||
Memory search must remain disabled.
|
||||
|
||||
```text
|
||||
允许最终晋升
|
||||
继续保持 memory search 关闭
|
||||
```
|
||||
|
||||
## Promotion Scope
|
||||
|
||||
Approved for V1R4C5:
|
||||
|
||||
1. SR-01 Gitea reliability and branch consistency guardrails.
|
||||
2. SR-02 watcher/stuck command cleanup.
|
||||
3. User data isolation redline and enforcement gates.
|
||||
4. SR-04 admin workbench read-only visibility preparation only.
|
||||
|
||||
## Explicit Non-Activation
|
||||
|
||||
The following are not approved by this promotion:
|
||||
|
||||
```text
|
||||
memory search activation
|
||||
full cross-session memory recall
|
||||
global vector index
|
||||
full SR-04 production portal rollout beyond read-only/admin visibility preparation
|
||||
bulk merge of old test/smoke/auth branches
|
||||
force-push based reconciliation
|
||||
```
|
||||
|
||||
## Required Runtime State
|
||||
|
||||
Memory remains disabled:
|
||||
|
||||
```text
|
||||
AIOS_MEMORY_ENABLED=false
|
||||
```
|
||||
|
||||
If a provider or deployment attempts to enable memory/search, it must be blocked unless a future owner approval explicitly allows it after the user-data isolation activation gate returns allowed.
|
||||
|
||||
## Final Promotion Rule
|
||||
|
||||
V1R4C5 may proceed to tag/promotion under owner gate.
|
||||
|
||||
If any final gate fails, promotion must stop and memory/search must remain disabled.
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"type": "branch",
|
||||
"branch": "feature/v1r4c4-owner-maintenance-gate-v2-20260710",
|
||||
"base": "main",
|
||||
"created_by": "chatgpt-gitops-bot",
|
||||
"created_at": "2026-07-10T10:32:35Z",
|
||||
"direct_main_push": false,
|
||||
"owner_approval_required": true
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
version: 1
|
||||
name: owner-maintenance-gate
|
||||
baseline: V1R4C3
|
||||
created_at: "2026-07-10"
|
||||
purpose: Owner-controlled non-dangerous maintenance permissions without arbitrary host CLI access.
|
||||
|
||||
principles:
|
||||
- agents_may_detect_and_request
|
||||
- owner_may_approve_non_dangerous_actions
|
||||
- runner_executes_only_allowlisted_command_keys
|
||||
- no_arbitrary_shell
|
||||
- protected_branch_merge_is_default_owner_gate
|
||||
- every_execution_must_be_audited
|
||||
|
||||
permission_tiers:
|
||||
READ_ONLY:
|
||||
agent_allowed: true
|
||||
owner_allowed: true
|
||||
requires_owner_gate: false
|
||||
AUTO_PATCH:
|
||||
agent_allowed: true
|
||||
owner_allowed: true
|
||||
requires_owner_gate: false
|
||||
OWNER_NON_DANGEROUS_ALL:
|
||||
description: Owner may execute all non-destructive allowlisted maintenance command_keys after owner gate approval.
|
||||
agent_allowed: false
|
||||
owner_allowed: true
|
||||
requires_owner_gate: true
|
||||
approval_model: protected_branch_merge_or_signed_owner_commit
|
||||
OWNER_HIGH_RISK:
|
||||
description: main merge, baseline promotion, tag creation, credential/provider mutation, destructive cleanup, production restart, SSH/firewall mutation.
|
||||
agent_allowed: false
|
||||
owner_allowed: true
|
||||
requires_owner_gate: true
|
||||
extra_review_required: true
|
||||
|
||||
safety_classification:
|
||||
non_dangerous_requirements:
|
||||
destructive: false
|
||||
arbitrary_shell: false
|
||||
credential_mutation: false
|
||||
provider_mutation: false
|
||||
external_network_write: false
|
||||
production_data_delete: false
|
||||
baseline_or_tag_mutation: false
|
||||
main_branch_direct_write: false
|
||||
command_key_must_be_allowlisted: true
|
||||
always_high_risk:
|
||||
- merge_to_main
|
||||
- baseline_promotion
|
||||
- tag_creation
|
||||
- credential_rotation
|
||||
- embedding_provider_change
|
||||
- database_delete_or_drop
|
||||
- rm_recursive_or_force
|
||||
- service_restart_production
|
||||
- firewall_or_ssh_config_change
|
||||
- arbitrary_bash_or_shell
|
||||
|
||||
allowlist:
|
||||
openclaw.memory.index.force:
|
||||
permission: OWNER_NON_DANGEROUS_ALL
|
||||
risk: medium
|
||||
destructive: false
|
||||
command_vector:
|
||||
- /usr/local/bin/openclaw
|
||||
- memory
|
||||
- index
|
||||
- --force
|
||||
timeout_seconds: 1800
|
||||
lock_key: memory-index-rebuild
|
||||
acceptance:
|
||||
- openclaw memory search "V1R4C3"
|
||||
- openclaw memory search "Gitea Branch Sync"
|
||||
- openclaw memory search "Autonomous Controller"
|
||||
success_signals:
|
||||
- AIOS_OWNER_MAINTENANCE_MEMORY_INDEX_REBUILT
|
||||
- AIOS_MEMORY_SEARCH_RESTORED
|
||||
|
||||
status: proposed
|
||||
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Owner maintenance allowlist runner.
|
||||
|
||||
Executes only approved command_key mappings. It never runs arbitrary shell strings.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
try:
|
||||
import yaml # type: ignore
|
||||
except Exception:
|
||||
yaml = None
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class AllowedCommand:
|
||||
command_key: str
|
||||
argv: tuple[str, ...]
|
||||
permission: str
|
||||
risk: str
|
||||
destructive: bool
|
||||
timeout_seconds: int
|
||||
|
||||
|
||||
ALLOWED_COMMANDS: dict[str, AllowedCommand] = {
|
||||
"openclaw.memory.index.force": AllowedCommand(
|
||||
command_key="openclaw.memory.index.force",
|
||||
argv=("/usr/local/bin/openclaw", "memory", "index", "--force"),
|
||||
permission="OWNER_NON_DANGEROUS_ALL",
|
||||
risk="medium",
|
||||
destructive=False,
|
||||
timeout_seconds=1800,
|
||||
),
|
||||
}
|
||||
|
||||
DENY_FLAGS = {
|
||||
"arbitrary_shell",
|
||||
"credential_mutation",
|
||||
"provider_mutation",
|
||||
"external_network_write",
|
||||
"production_data_delete",
|
||||
"baseline_or_tag_mutation",
|
||||
"main_branch_direct_write",
|
||||
}
|
||||
|
||||
|
||||
def sha256_text(value: str) -> str:
|
||||
return hashlib.sha256(value.encode("utf-8", errors="replace")).hexdigest()
|
||||
|
||||
|
||||
def utc_now() -> str:
|
||||
return datetime.now(timezone.utc).isoformat()
|
||||
|
||||
|
||||
def load_request(path: Path) -> dict[str, Any]:
|
||||
if yaml is None:
|
||||
raise RuntimeError("PyYAML is required to load owner request YAML")
|
||||
data = yaml.safe_load(path.read_text(encoding="utf-8"))
|
||||
if not isinstance(data, dict):
|
||||
raise ValueError("owner request must be a YAML object")
|
||||
return data
|
||||
|
||||
|
||||
def validate_request(req: dict[str, Any]) -> AllowedCommand:
|
||||
command_key = req.get("command_key")
|
||||
if command_key not in ALLOWED_COMMANDS:
|
||||
raise PermissionError(f"command_key is not allowlisted: {command_key}")
|
||||
allowed = ALLOWED_COMMANDS[command_key]
|
||||
if req.get("permission") != allowed.permission:
|
||||
raise PermissionError("request permission does not match allowlist")
|
||||
safety = req.get("safety", {})
|
||||
if not isinstance(safety, dict):
|
||||
raise PermissionError("safety metadata is required")
|
||||
if bool(safety.get("destructive", True)) != allowed.destructive:
|
||||
raise PermissionError("destructive flag does not match allowlist")
|
||||
denied = [flag for flag in DENY_FLAGS if safety.get(flag) is True]
|
||||
if denied:
|
||||
raise PermissionError(f"denied safety flags: {denied}")
|
||||
gate = req.get("owner_gate", {})
|
||||
if not isinstance(gate, dict) or gate.get("required") is not True:
|
||||
raise PermissionError("owner_gate.required must be true")
|
||||
if not gate.get("approved_by") or not gate.get("approved_at") or not gate.get("approval_commit"):
|
||||
raise PermissionError("owner approval fields are required before execution")
|
||||
return allowed
|
||||
|
||||
|
||||
def run_allowed_command(allowed: AllowedCommand, dry_run: bool) -> dict[str, Any]:
|
||||
if dry_run:
|
||||
return {"dry_run": True, "argv": list(allowed.argv), "exit_code": None}
|
||||
proc = subprocess.run(
|
||||
list(allowed.argv),
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=allowed.timeout_seconds,
|
||||
)
|
||||
return {
|
||||
"dry_run": False,
|
||||
"argv": list(allowed.argv),
|
||||
"exit_code": proc.returncode,
|
||||
"executed_at": utc_now(),
|
||||
"stdout_sha256": sha256_text(proc.stdout),
|
||||
"stderr_sha256": sha256_text(proc.stderr),
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Run an owner-approved allowlisted maintenance request")
|
||||
parser.add_argument("request", type=Path)
|
||||
parser.add_argument("--dry-run", action="store_true")
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
req = load_request(args.request)
|
||||
allowed = validate_request(req)
|
||||
result = run_allowed_command(allowed, dry_run=args.dry_run)
|
||||
print(json.dumps({"status": "ok", "command_key": allowed.command_key, "result": result}, indent=2))
|
||||
return 0 if result.get("exit_code") in (None, 0) else int(result["exit_code"])
|
||||
except Exception as exc:
|
||||
print(json.dumps({"status": "error", "error": str(exc)}, indent=2), file=sys.stderr)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,54 +0,0 @@
|
||||
{
|
||||
"version": "V1R4C5",
|
||||
"codename": "C5 reliability-security-admin-readonly",
|
||||
"status": "tagged-promotion-pending",
|
||||
"tag": "V1R4C5",
|
||||
"tag_commit": "d457ac396147043ed5d0a3fd8b44bcb10f48bceb",
|
||||
"tag_remote_verified": true,
|
||||
"base_baseline": "V1R4C3",
|
||||
"previous_baseline": "V1R4C3",
|
||||
"created_at": "2026-07-11",
|
||||
"created_by": "chatgpt-gitops-bot",
|
||||
"release_type": "controlled-integration",
|
||||
"promotion_policy": "owner-gated",
|
||||
"owner_approval": {
|
||||
"final_promotion_approved": true,
|
||||
"memory_search_enabled": false,
|
||||
"force_push_allowed": false
|
||||
},
|
||||
"scope": {
|
||||
"included": [
|
||||
"SR-01 Gitea reliability and branch consistency guardrails",
|
||||
"SR-02 watcher/stuck command cleanup",
|
||||
"User data isolation redline and enforcement gates",
|
||||
"SR-04 admin workbench read-only visibility preparation"
|
||||
],
|
||||
"excluded": [
|
||||
"memory search activation",
|
||||
"full cross-session memory recall",
|
||||
"global vector index",
|
||||
"full SR-04 production portal rollout",
|
||||
"bulk merge of old test/smoke/auth branches",
|
||||
"force-push based reconciliation"
|
||||
]
|
||||
},
|
||||
"acceptance": {
|
||||
"runtime_status": "active",
|
||||
"runtime_write_acceptance": "passed-clean-branch",
|
||||
"gitea_sentinel": "healthy-before-final-promotion-check-required",
|
||||
"sr02_tests": "11/11 pass; rerun on final integration candidate required",
|
||||
"user_data_isolation": "gate implemented; memory remains disabled",
|
||||
"admin_workbench": "read-only visibility preparation only"
|
||||
},
|
||||
"deployment_constraints": {
|
||||
"AIOS_MEMORY_ENABLED": false,
|
||||
"memory_search_activation_requires_future_owner_approval": true,
|
||||
"gitea_db_mutation_requires_owner_admin_approval": true,
|
||||
"sr04_full_rollout_deferred": true
|
||||
},
|
||||
"rollback_policy": {
|
||||
"memory_search": "remain disabled",
|
||||
"sr04": "disable read-only visibility slice if RBAC or isolation check fails",
|
||||
"gitea": "enter autonomous safe mode if branch consistency drift detected"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user