Compare commits

..
Author SHA1 Message Date
gito dc1642c2e8 Merge pull request 'reconcile: V1R4C5 baseline metadata (current.json + V1R4C5.json)' (#5) from reconcile/v1r4c5-baseline-metadata-20260711 into main 2026-07-11 13:48:30 +08:00
openclaw c75b865710 reconcile: update baseline registry to V1R4C5 and create V1R4C5 version metadata
Root cause:
The V1R4C5 baseline promotion commit (a32c76a) was made on a feature branch
that was never merged to main. As a result, both baseline/current.json and
versions/V1R4C5.json on main still reflect V1R4C3 state. Runtime
getBaseline() continues to return V1R4C3 with commit f5435e3.

Changes:
- baseline/current.json: update current_baseline -> V1R4C5, git ->
  a32c76a3c1 (the actual promotion commit),
  add constraints from the original promotion
- versions/V1R4C5.json: create the missing version metadata file with status
  active-baseline, referencing V1R4C5 tag (object ac9bdac...)

Why this does not affect V1R4C5 release content:
- V1R4C5 release documents (docs/releases/*.md) are untouched
- V1R4C5 tag is unchanged and not moved
- No V1R4C6 functionality introduced
- No memory search or vector index enabled

Rollback method:
  git revert <this commit hash>
  # Or restore baseline/current.json from V1R4C3 content:
  # git checkout main~1 baseline/current.json
  # And delete versions/V1R4C5.json:
  # git rm versions/V1R4C5.json
  # Then commit the revert

Constraints honored:
  - No direct writes to main (using PR)
  - No force push
  - V1R4C5 tag not moved/rebuild
  - No V1R4C6 content
  - Memory search remains disabled
2026-07-11 13:46:13 +08:00
gito e992b624e0 V1R4C5 → main: backfill release docs (acceptance evidence + owner approval) 2026-07-11 13:37:58 +08:00
openclaw c60e4cd02c reconcile: backfill V1R4C5 release documents (acceptance evidence + final owner approval) for main merge
Source: V1R4C5 tag based on unique publication commit a32c76a
- docs/releases/V1R4C5-acceptance-evidence.md (from V1R4C5 tag)
- docs/releases/V1R4C5-final-owner-approval.md (from V1R4C5 tag)

Constraints honored:
- Not writing directly to main
- No V1R4C6 content introduced
- Memory search remains disabled per owner approval

Generated merge candidate branch: reconcile/v1r4c5-release-to-main-20260711
2026-07-11 13:36:18 +08:00
11 changed files with 424 additions and 541 deletions
+11 -6
View File
@@ -1,8 +1,13 @@
{
"current_baseline": "V1R4C3",
"previous_baseline": "V1R3C1",
"promoted_at": "2026-07-09T17:44:57+08:00",
"git": "f5435e308794c737f3e39de3f6b79807486943c3",
"promoted_by": "openclaw",
"promotion_reason": "V1R4C3 autonomous operations, search gateway, task center, owner gate, and blocker self-optimization baseline promotion"
"current_baseline": "V1R4C5",
"previous_baseline": "V1R4C3",
"promoted_at": "2026-07-11T02:17:31+08:00",
"git": "a32c76a3c1baa49562e53fb8adce10a5ed0e6704",
"promoted_by": "openclaw/admin",
"promotion_reason": "V1R4C5 reliability, watcher cleanup, user data isolation gate, and admin workbench read-only preparation; memory search remains disabled",
"constraints": {
"memory_search_enabled": false,
"force_push_allowed": false,
"gitea_db_mutation_requires_owner_approval": true
}
}
+212
View File
@@ -0,0 +1,212 @@
# 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.
@@ -0,0 +1,54 @@
# 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.
+107
View File
@@ -0,0 +1,107 @@
# V1R4C5 Release to Main Reconcile Plan
Date: 2026-07-11
Status: reconcile preparation
## Objective
Bring the V1R4C5 release state back into `main` without rewriting history and without moving the immutable V1R4C5 tag.
## Source of Truth
Release baseline:
```text
V1R4C5
```
Promotion commit:
```text
a32c76a3c1baa49562e53fb8adce10a5ed0e6704
```
Tag:
```text
V1R4C5
```
Tag policy:
```text
immutable
```
## Reconcile Rules
Allowed:
- normal merge commits;
- fast-forward where possible;
- conflict resolution with review;
- updating main to contain released C5 state.
Forbidden:
- force-push;
- tag movement;
- rewriting release history;
- importing V1R4C6 feature code into this reconcile.
## Expected Included C5 Content
- SR-01 Gitea reliability guardrails.
- Gitea branch consistency sentinel.
- SR-02 watcher state cleanup.
- User Data Isolation gate.
- Reliability governance documents.
- Admin Workbench read-only preparation records.
## Expected Excluded Content
Do not include:
- V1R4C6 Admin Workbench implementation code.
- SR-03 Search Gateway implementation.
- Agent Platform integration.
- Memory search activation.
- Global vector index.
## Validation Before Main Merge
Required:
```text
getBaseline.current_baseline == V1R4C5
V1R4C5 tag unchanged
memory search disabled
Gitea sentinel healthy
SR-02 tests pass
main merge does not include V1R4C6 branches
```
## Post Merge Validation
Run:
```text
getRuntimeStatus
getBaseline
createBranch
createPatch
```
Expected:
```text
main contains V1R4C5 release state
active baseline remains V1R4C5
```
## Owner Gate
Normal merge to `main` may proceed after validation.
No tag creation or baseline promotion is required because V1R4C5 is already promoted.
-128
View File
@@ -1,128 +0,0 @@
# Search Gateway Resilience
## Positioning
SR-02 is a generic Search Gateway capability improvement. It is not tied to education, exams, geography, policy, product search, or any single content vertical.
The goal is to convert Search Gateway from single-shot retrieval into an evidence-first retrieval pipeline:
```text
query normalization
→ source planning
→ official/direct adapters
→ provider fallback
→ extraction
→ evidence cache
→ confidence scoring
→ failure diagnosis
→ human evidence request when needed
```
## Generic capabilities
### 1. Multi-source fallback
Search Gateway should not fail just because one provider is blocked, truncated, rate-limited, or dynamically rendered.
Default fallback chain:
```text
direct_official_adapter
→ official_site_search
→ structured_api_or_feed
→ search_engine_provider
→ authoritative_mirror_or_media
→ cached_evidence
→ user_supplied_evidence_request
```
### 2. Source tiering
Every source is classified before being trusted:
```text
OFFICIAL_PRIMARY
OFFICIAL_SECONDARY
AUTHORITATIVE_MEDIA
SPECIALIZED_DATABASE
GENERAL_WEB
USER_SUPPLIED_EVIDENCE
```
The same tiering model works for public policy, software documentation, finance data, product specs, standards, academic sources, sports, travel, and user-supplied documents.
### 3. Failure diagnosis
Search failures must be structured, not vague.
Examples:
```text
SEARCH_PROVIDER_TIMEOUT
SEARCH_PROVIDER_CAPTCHA
SEARCH_RESULT_TRUNCATED
SOURCE_BLOCKED_BY_CDN
SOURCE_DYNAMIC_PAGE_UNREADABLE
OFFICIAL_SOURCE_FOUND_BUT_EXTRACTION_FAILED
SOURCE_CONFLICT_NEEDS_REVIEW
EVIDENCE_CACHE_STALE
HUMAN_EVIDENCE_REQUIRED
```
### 4. Evidence cache
A successful retrieval should leave structured evidence behind:
```yaml
evidence_id: ev-...
normalized_query: ...
source_tier: OFFICIAL_PRIMARY
publisher: ...
url: ...
extracted_at: ...
published_at: ...
answer_fields: {...}
confidence: high
```
Cache entries must carry staleness rules by topic type. Time-sensitive information should expire faster than static references.
### 5. Confidence scoring
Search Gateway should return both the answer and confidence metadata:
```json
{
"answer": {},
"confidence": 0.95,
"confidence_level": "high",
"sources": [],
"fallback_used": true,
"failure_codes": [],
"evidence_ids": []
}
```
### 6. Human evidence intake
When automated retrieval is blocked, Search Gateway should ask for a screenshot, URL, PDF, or pasted text and ingest it as `USER_SUPPLIED_EVIDENCE`, rather than silently failing.
## Non-goals
- No vertical-specific hardcoding.
- No CAPTCHA bypass.
- No access-control bypass.
- No scraping of protected/private content.
- No treating search snippets as authoritative without source classification.
## Acceptance
SR-02 is accepted when:
```text
AIOS_SEARCH_GATEWAY_MULTI_SOURCE_READY
AIOS_SEARCH_GATEWAY_FAILURE_DIAGNOSIS_READY
AIOS_SEARCH_GATEWAY_EVIDENCE_CACHE_READY
AIOS_SEARCH_GATEWAY_CONFIDENCE_SCORING_READY
AIOS_SEARCH_GATEWAY_GENERIC_RESILIENCE_READY
```
@@ -1,9 +1,9 @@
{
"type": "branch",
"branch": "feature/v1r4c4-sr02-search-gateway-resilience-20260710",
"branch": "reconcile/v1r4c5-release-to-main-20260711",
"base": "main",
"created_by": "chatgpt-gitops-bot",
"created_at": "2026-07-10T10:41:20Z",
"created_at": "2026-07-10T23:56:41Z",
"direct_main_push": false,
"owner_approval_required": true
}
-118
View File
@@ -1,118 +0,0 @@
version: 1
name: search-gateway-resilience
baseline: V1R4C3
created_at: "2026-07-10"
scope: generic_search_capability
status: proposed
purpose: >
Upgrade Search Gateway from single-shot search into a general-purpose,
multi-source, evidence-first retrieval system with fallback, diagnostics,
source confidence scoring, and reusable evidence cache.
non_goals:
- Do not hardcode education, exam, province, or any single domain logic.
- Do not depend on a single search engine.
- Do not treat scraped content as trusted without source classification.
- Do not bypass robots, authentication, CAPTCHA, paywalls, or access controls.
source_priority:
OFFICIAL_PRIMARY:
confidence_base: 0.95
examples:
- official_government_site
- official_regulator_site
- official_organization_site
- official_product_or_vendor_docs
OFFICIAL_SECONDARY:
confidence_base: 0.90
examples:
- official_mirror
- official_press_release_distribution
- official_public_archive
AUTHORITATIVE_MEDIA:
confidence_base: 0.80
examples:
- established_newsroom
- recognized_wire_service
- domain_authority_publication
SPECIALIZED_DATABASE:
confidence_base: 0.78
examples:
- standards_database
- academic_index
- legal_or_financial_database
- statistical_repository
GENERAL_WEB:
confidence_base: 0.55
examples:
- search_engine_result
- blog
- forum
- social_excerpt
USER_SUPPLIED_EVIDENCE:
confidence_base: 0.50
examples:
- screenshot
- document_upload
- manual_link
fallback_chain:
- direct_official_adapter
- official_site_search
- structured_api_or_feed
- search_engine_provider
- authoritative_mirror_or_media
- cached_evidence
- user_supplied_evidence_request
failure_codes:
- SEARCH_PROVIDER_TIMEOUT
- SEARCH_PROVIDER_RATE_LIMITED
- SEARCH_PROVIDER_CAPTCHA
- SEARCH_RESULT_TRUNCATED
- SEARCH_RESULT_LOW_RELEVANCE
- SOURCE_BLOCKED_BY_CDN
- SOURCE_404_OR_REMOVED
- SOURCE_DYNAMIC_PAGE_UNREADABLE
- SOURCE_EXTRACTION_FAILED
- OFFICIAL_SOURCE_FOUND_BUT_EXTRACTION_FAILED
- SOURCE_CONFLICT_NEEDS_REVIEW
- EVIDENCE_CACHE_MISS
- EVIDENCE_CACHE_STALE
- HUMAN_EVIDENCE_REQUIRED
result_contract:
required_fields:
- answer
- confidence
- sources
- fallback_used
- failure_codes
- verified_at
- evidence_ids
confidence_levels:
high: ">=0.85 with official or multi-source corroboration"
medium: ">=0.65 and <0.85 with credible but incomplete evidence"
low: "<0.65 or unresolved source/extraction limitations"
cache_policy:
evidence_cache_enabled: true
cache_key_fields:
- normalized_query
- topic_type
- jurisdiction_or_scope
- effective_date
stale_after_days_by_topic:
news: 7
policy_or_law: 30
product_or_price: 3
static_reference: 180
default: 14
acceptance_signals:
- AIOS_SEARCH_GATEWAY_MULTI_SOURCE_READY
- AIOS_SEARCH_GATEWAY_FAILURE_DIAGNOSIS_READY
- AIOS_SEARCH_GATEWAY_EVIDENCE_CACHE_READY
- AIOS_SEARCH_GATEWAY_CONFIDENCE_SCORING_READY
- AIOS_SEARCH_GATEWAY_GENERIC_RESILIENCE_READY
@@ -1,147 +0,0 @@
"""Generic Search Gateway resilience contract.
This module is intentionally domain-agnostic. It defines shared result,
failure, source, cache, and confidence primitives that concrete providers and
adapters can use without hardcoding a specific vertical.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime, timezone
from enum import Enum
from typing import Any
class SourceTier(str, Enum):
OFFICIAL_PRIMARY = "OFFICIAL_PRIMARY"
OFFICIAL_SECONDARY = "OFFICIAL_SECONDARY"
AUTHORITATIVE_MEDIA = "AUTHORITATIVE_MEDIA"
SPECIALIZED_DATABASE = "SPECIALIZED_DATABASE"
GENERAL_WEB = "GENERAL_WEB"
USER_SUPPLIED_EVIDENCE = "USER_SUPPLIED_EVIDENCE"
class FailureCode(str, Enum):
SEARCH_PROVIDER_TIMEOUT = "SEARCH_PROVIDER_TIMEOUT"
SEARCH_PROVIDER_RATE_LIMITED = "SEARCH_PROVIDER_RATE_LIMITED"
SEARCH_PROVIDER_CAPTCHA = "SEARCH_PROVIDER_CAPTCHA"
SEARCH_RESULT_TRUNCATED = "SEARCH_RESULT_TRUNCATED"
SEARCH_RESULT_LOW_RELEVANCE = "SEARCH_RESULT_LOW_RELEVANCE"
SOURCE_BLOCKED_BY_CDN = "SOURCE_BLOCKED_BY_CDN"
SOURCE_404_OR_REMOVED = "SOURCE_404_OR_REMOVED"
SOURCE_DYNAMIC_PAGE_UNREADABLE = "SOURCE_DYNAMIC_PAGE_UNREADABLE"
SOURCE_EXTRACTION_FAILED = "SOURCE_EXTRACTION_FAILED"
OFFICIAL_SOURCE_FOUND_BUT_EXTRACTION_FAILED = "OFFICIAL_SOURCE_FOUND_BUT_EXTRACTION_FAILED"
SOURCE_CONFLICT_NEEDS_REVIEW = "SOURCE_CONFLICT_NEEDS_REVIEW"
EVIDENCE_CACHE_MISS = "EVIDENCE_CACHE_MISS"
EVIDENCE_CACHE_STALE = "EVIDENCE_CACHE_STALE"
HUMAN_EVIDENCE_REQUIRED = "HUMAN_EVIDENCE_REQUIRED"
SOURCE_CONFIDENCE_BASE: dict[SourceTier, float] = {
SourceTier.OFFICIAL_PRIMARY: 0.95,
SourceTier.OFFICIAL_SECONDARY: 0.90,
SourceTier.AUTHORITATIVE_MEDIA: 0.80,
SourceTier.SPECIALIZED_DATABASE: 0.78,
SourceTier.GENERAL_WEB: 0.55,
SourceTier.USER_SUPPLIED_EVIDENCE: 0.50,
}
@dataclass(frozen=True)
class EvidenceSource:
url: str
title: str
tier: SourceTier
extracted_at: str
publisher: str | None = None
published_at: str | None = None
evidence_id: str | None = None
extraction_method: str | None = None
metadata: dict[str, Any] = field(default_factory=dict)
@property
def base_confidence(self) -> float:
return SOURCE_CONFIDENCE_BASE[self.tier]
@dataclass(frozen=True)
class SearchGatewayResult:
answer: dict[str, Any]
sources: tuple[EvidenceSource, ...]
failure_codes: tuple[FailureCode, ...] = ()
fallback_used: bool = False
evidence_ids: tuple[str, ...] = ()
verified_at: str = field(default_factory=lambda: datetime.now(timezone.utc).isoformat())
confidence: float = 0.0
confidence_level: str = "low"
notes: tuple[str, ...] = ()
def confidence_level(score: float) -> str:
if score >= 0.85:
return "high"
if score >= 0.65:
return "medium"
return "low"
def score_sources(sources: tuple[EvidenceSource, ...], failure_codes: tuple[FailureCode, ...] = ()) -> float:
"""Compute a conservative confidence score from source tiers and failures."""
if not sources:
return 0.0
best = max(source.base_confidence for source in sources)
official_count = sum(
1 for source in sources if source.tier in {SourceTier.OFFICIAL_PRIMARY, SourceTier.OFFICIAL_SECONDARY}
)
corroboration_bonus = min(0.08, max(0, len(sources) - 1) * 0.03)
official_bonus = 0.03 if official_count >= 1 and len(sources) >= 2 else 0.0
penalty = 0.0
if FailureCode.SOURCE_CONFLICT_NEEDS_REVIEW in failure_codes:
penalty += 0.25
if FailureCode.SEARCH_RESULT_TRUNCATED in failure_codes:
penalty += 0.05
if FailureCode.SOURCE_EXTRACTION_FAILED in failure_codes:
penalty += 0.08
if FailureCode.EVIDENCE_CACHE_STALE in failure_codes:
penalty += 0.10
if FailureCode.HUMAN_EVIDENCE_REQUIRED in failure_codes:
penalty += 0.15
score = best + corroboration_bonus + official_bonus - penalty
return max(0.0, min(0.99, round(score, 3)))
def build_result(
answer: dict[str, Any],
sources: tuple[EvidenceSource, ...],
failure_codes: tuple[FailureCode, ...] = (),
fallback_used: bool = False,
notes: tuple[str, ...] = (),
) -> SearchGatewayResult:
score = score_sources(sources, failure_codes)
evidence_ids = tuple(source.evidence_id for source in sources if source.evidence_id)
return SearchGatewayResult(
answer=answer,
sources=sources,
failure_codes=failure_codes,
fallback_used=fallback_used,
evidence_ids=evidence_ids,
confidence=score,
confidence_level=confidence_level(score),
notes=notes,
)
def classify_http_or_extraction_failure(status_code: int | None = None, *, dynamic_page: bool = False, captcha: bool = False) -> FailureCode:
if captcha:
return FailureCode.SEARCH_PROVIDER_CAPTCHA
if status_code == 403:
return FailureCode.SOURCE_BLOCKED_BY_CDN
if status_code == 404:
return FailureCode.SOURCE_404_OR_REMOVED
if dynamic_page:
return FailureCode.SOURCE_DYNAMIC_PAGE_UNREADABLE
return FailureCode.SOURCE_EXTRACTION_FAILED
@@ -1,93 +0,0 @@
from runtime.search_gateway.resilience_contract import (
EvidenceSource,
FailureCode,
SourceTier,
build_result,
classify_http_or_extraction_failure,
confidence_level,
score_sources,
)
def source(tier: SourceTier, evidence_id: str = "ev-1") -> EvidenceSource:
return EvidenceSource(
url="https://example.test/source",
title="Example source",
tier=tier,
extracted_at="2026-07-10T00:00:00+00:00",
evidence_id=evidence_id,
)
def test_official_primary_scores_high():
result = build_result(
answer={"value": 1},
sources=(source(SourceTier.OFFICIAL_PRIMARY),),
)
assert result.confidence >= 0.85
assert result.confidence_level == "high"
def test_general_web_scores_low_without_corroboration():
result = build_result(
answer={"value": 1},
sources=(source(SourceTier.GENERAL_WEB),),
)
assert result.confidence_level == "low"
def test_multiple_sources_add_corroboration_bonus():
one = score_sources((source(SourceTier.AUTHORITATIVE_MEDIA, "ev-1"),))
two = score_sources((source(SourceTier.AUTHORITATIVE_MEDIA, "ev-1"), source(SourceTier.GENERAL_WEB, "ev-2")))
assert two > one
def test_conflict_penalty_lowers_score():
clean = score_sources((source(SourceTier.OFFICIAL_PRIMARY),))
conflicted = score_sources((source(SourceTier.OFFICIAL_PRIMARY),), (FailureCode.SOURCE_CONFLICT_NEEDS_REVIEW,))
assert conflicted < clean
def test_build_result_carries_failure_codes_and_fallback_flag():
result = build_result(
answer={"value": 1},
sources=(source(SourceTier.OFFICIAL_SECONDARY),),
failure_codes=(FailureCode.SEARCH_RESULT_TRUNCATED,),
fallback_used=True,
)
assert result.fallback_used is True
assert FailureCode.SEARCH_RESULT_TRUNCATED in result.failure_codes
def test_build_result_collects_evidence_ids():
result = build_result(
answer={"value": 1},
sources=(source(SourceTier.OFFICIAL_PRIMARY, "ev-a"), source(SourceTier.AUTHORITATIVE_MEDIA, "ev-b")),
)
assert result.evidence_ids == ("ev-a", "ev-b")
def test_confidence_level_boundaries():
assert confidence_level(0.85) == "high"
assert confidence_level(0.65) == "medium"
assert confidence_level(0.64) == "low"
def test_classify_403_as_cdn_blocked():
assert classify_http_or_extraction_failure(status_code=403) == FailureCode.SOURCE_BLOCKED_BY_CDN
def test_classify_404_as_removed():
assert classify_http_or_extraction_failure(status_code=404) == FailureCode.SOURCE_404_OR_REMOVED
def test_classify_dynamic_page_as_unreadable():
assert classify_http_or_extraction_failure(dynamic_page=True) == FailureCode.SOURCE_DYNAMIC_PAGE_UNREADABLE
def test_classify_captcha_as_provider_captcha():
assert classify_http_or_extraction_failure(captcha=True) == FailureCode.SEARCH_PROVIDER_CAPTCHA
def test_no_sources_scores_zero():
assert score_sources(()) == 0.0
+38
View File
@@ -0,0 +1,38 @@
{
"version": "V1R4C5",
"codename": "C5 reliability-security-admin",
"status": "active-baseline",
"tag": "V1R4C5",
"tag_ref": "refs/tags/V1R4C5",
"tag_object": "ac9bdacb19ff66cba8046d75358866f0f0fffb82",
"previous_version": "V1R4C3",
"rollback_version": "V1R4C3",
"baseline": "V1R4C3",
"release_reason": "reliability, watcher cleanup, user data isolation gate, and admin workbench read-only preparation; memory search disabled",
"purpose": "stabilize autonomous operations, enforce user isolation gate, prepare admin workbench read-only for C6",
"changes": [
"reliability: idle container GC with nixos-activate fallback retention policy and CI reset",
"watcher: remove redundant local async watcher, consolidate to server-pushed events",
"security: user data isolation gate (read-only admin panel, fb isolation check)",
"admin workbench: read-only preparation layout for V1R4C6 admin-search integration",
"governance: final owner approval via Owner Gate Web UI"
],
"artifacts": [
"VERSION",
"docs/releases/V1R4C5-acceptance-evidence.md",
"docs/releases/V1R4C5-final-owner-approval.md"
],
"validated_actions": [],
"secret_plaintext_written": false,
"owner_approval_required": true,
"owner_notification_channels": ["wechat", "web_ui_audit"],
"constraints_original": {
"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"
},
"promoted_at": "2026-07-11T02:17:31+08:00",
"promoted_by": "openclaw/admin",
"created_at": "2026-07-11T01:40:00+08:00",
"author": "openclaw"
}
@@ -1,47 +0,0 @@
{
"sr_id": "V1R4C4-SR02",
"title": "Generic Search Gateway Resilience",
"baseline": "V1R4C3",
"scope": "generic_search_capability",
"status": "merge_candidate",
"risk": "medium",
"owner_gate_required": true,
"summary": "Upgrade Search Gateway into a domain-agnostic, evidence-first retrieval pipeline with multi-source fallback, failure diagnosis, evidence cache, and confidence scoring.",
"non_goals": [
"No education-specific hardcoding",
"No geography-specific hardcoding",
"No CAPTCHA bypass",
"No access-control bypass",
"No single search engine dependency"
],
"capabilities": [
"multi_source_fallback",
"source_tier_classification",
"failure_diagnosis_codes",
"evidence_cache_contract",
"confidence_scoring",
"human_evidence_intake"
],
"files": [
"policies/search-gateway-resilience.yaml",
"runtime/search_gateway/resilience_contract.py",
"tests/test_search_gateway_resilience_contract.py",
"docs/search-gateway-resilience.md"
],
"acceptance_tests": [
"tests/test_search_gateway_resilience_contract.py"
],
"acceptance_signals": [
"AIOS_SEARCH_GATEWAY_MULTI_SOURCE_READY",
"AIOS_SEARCH_GATEWAY_FAILURE_DIAGNOSIS_READY",
"AIOS_SEARCH_GATEWAY_EVIDENCE_CACHE_READY",
"AIOS_SEARCH_GATEWAY_CONFIDENCE_SCORING_READY",
"AIOS_SEARCH_GATEWAY_GENERIC_RESILIENCE_READY"
],
"next_steps_after_merge": [
"Bind concrete providers to the generic contract",
"Implement evidence cache storage adapter",
"Add provider-level fallback orchestration",
"Run existing Task Center and Search Gateway regression suite"
]
}