fix(agent): persist no-write learning receipts
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m19s
CD Pipeline / build-and-deploy (push) Successful in 9m4s
CD Pipeline / post-deploy-checks (push) Successful in 2m0s
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m19s
CD Pipeline / build-and-deploy (push) Successful in 9m4s
CD Pipeline / post-deploy-checks (push) Successful in 2m0s
This commit is contained in:
@@ -3264,7 +3264,7 @@ jobs:
|
||||
}
|
||||
echo "executor_boundary_stage=live_socket_boundary_verified"
|
||||
|
||||
read_workload_db_identity() {
|
||||
read_workload_db_identity_once() {
|
||||
workload="$1"
|
||||
container="$2"
|
||||
representative_probe_count="$3"
|
||||
@@ -3412,6 +3412,23 @@ jobs:
|
||||
asyncio.run(main())
|
||||
PY
|
||||
}
|
||||
read_workload_db_identity() {
|
||||
workload="$1"
|
||||
attempt=1
|
||||
while [ "$attempt" -le 3 ]; do
|
||||
if identity_output=$(read_workload_db_identity_once "$@"); then
|
||||
printf '%s\n' "$identity_output"
|
||||
return 0
|
||||
fi
|
||||
echo "workload_db_identity_exec_retry=$attempt/3;workload=$workload" >&2
|
||||
if [ "$attempt" -lt 3 ]; then
|
||||
sleep $((attempt * 3))
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
echo "workload_db_identity_exec_exhausted=3;workload=$workload" >&2
|
||||
return 1
|
||||
}
|
||||
json_field() {
|
||||
field="$1"
|
||||
python3 -c \
|
||||
|
||||
@@ -153,6 +153,16 @@ _ENUM_FALLBACKS = {
|
||||
}
|
||||
|
||||
|
||||
def _knowledge_enum_db_label(value):
|
||||
"""Match the mixed-case labels in the deployed PostgreSQL enums."""
|
||||
|
||||
if isinstance(value, EntryStatus) and value is EntryStatus.PUBLISHED:
|
||||
return value.value
|
||||
if isinstance(value, EntryType | EntrySource | EntryStatus):
|
||||
return value.name
|
||||
return value
|
||||
|
||||
|
||||
def _enum_member(value, enum_cls):
|
||||
if value is None:
|
||||
return _ENUM_FALLBACKS.get(enum_cls)
|
||||
@@ -287,11 +297,11 @@ class KnowledgeDBRepository:
|
||||
values = {
|
||||
"title": data.title,
|
||||
"content": data.content,
|
||||
"entry_type": data.entry_type.value if hasattr(data.entry_type, "value") else data.entry_type,
|
||||
"entry_type": _knowledge_enum_db_label(data.entry_type),
|
||||
"category": data.category,
|
||||
"tags": data.tags,
|
||||
"source": data.source.value if hasattr(data.source, "value") else data.source,
|
||||
"status": data.status.value if hasattr(data.status, "value") else data.status,
|
||||
"source": _knowledge_enum_db_label(data.source),
|
||||
"status": _knowledge_enum_db_label(data.status),
|
||||
"related_incident_id": data.related_incident_id,
|
||||
"related_playbook_id": data.related_playbook_id,
|
||||
"related_approval_id": data.related_approval_id,
|
||||
@@ -313,7 +323,7 @@ class KnowledgeDBRepository:
|
||||
"title": data.title,
|
||||
"content": data.content,
|
||||
"tags": data.tags,
|
||||
"status": data.status.value if hasattr(data.status, "value") else data.status,
|
||||
"status": _knowledge_enum_db_label(data.status),
|
||||
"related_approval_id": data.related_approval_id,
|
||||
},
|
||||
)
|
||||
@@ -339,12 +349,12 @@ class KnowledgeDBRepository:
|
||||
record = KnowledgeEntryRecord(
|
||||
title=data.title,
|
||||
content=data.content,
|
||||
entry_type=data.entry_type,
|
||||
entry_type=_knowledge_enum_db_label(data.entry_type),
|
||||
category=data.category,
|
||||
tags=data.tags,
|
||||
source=data.source,
|
||||
source=_knowledge_enum_db_label(data.source),
|
||||
# 2026-04-04 ogt: Phase 25 P1 — 支援指定 status(ANTI_PATTERN 直接 PUBLISHED)
|
||||
status=data.status,
|
||||
status=_knowledge_enum_db_label(data.status),
|
||||
related_incident_id=data.related_incident_id,
|
||||
related_playbook_id=data.related_playbook_id,
|
||||
related_approval_id=data.related_approval_id,
|
||||
|
||||
@@ -12,6 +12,7 @@ from src.repositories.knowledge_repository import (
|
||||
_ASSET_TAXONOMY_KEYS,
|
||||
KnowledgeDBRepository,
|
||||
_enum_text,
|
||||
_knowledge_enum_db_label,
|
||||
)
|
||||
|
||||
|
||||
@@ -263,3 +264,12 @@ def test_enum_text_helper_casts_status_to_lowercase_text() -> None:
|
||||
|
||||
assert "lower(cast(knowledge_entries.status as varchar))" in compiled
|
||||
assert "archived" in compiled
|
||||
|
||||
|
||||
def test_knowledge_enum_db_labels_match_deployed_postgresql_contract() -> None:
|
||||
assert _knowledge_enum_db_label(EntryType.INCIDENT_CASE) == "INCIDENT_CASE"
|
||||
assert _knowledge_enum_db_label(EntryType.ANTI_PATTERN) == "ANTI_PATTERN"
|
||||
assert _knowledge_enum_db_label(EntrySource.AI_EXTRACTED) == "AI_EXTRACTED"
|
||||
assert _knowledge_enum_db_label(EntrySource.HUMAN) == "HUMAN"
|
||||
assert _knowledge_enum_db_label(EntryStatus.DRAFT) == "DRAFT"
|
||||
assert _knowledge_enum_db_label(EntryStatus.PUBLISHED) == "published"
|
||||
|
||||
@@ -264,6 +264,10 @@ def test_cd_prunes_and_verifies_api_executor_boundary_in_production() -> None:
|
||||
assert "read_workload_db_identity awoooi-api api 1 8" in workflow
|
||||
assert "read_workload_db_identity awoooi-worker worker 1 5" in workflow
|
||||
assert "awoooi-ansible-executor-broker broker 1 2" in workflow
|
||||
assert "read_workload_db_identity_once" in workflow
|
||||
assert 'while [ "$attempt" -le 3 ]' in workflow
|
||||
assert "workload_db_identity_exec_retry=$attempt/3" in workflow
|
||||
assert "workload_db_identity_exec_exhausted=3" in workflow
|
||||
assert "AWOOOI_DB_REPRESENTATIVE_PROBE_COUNT" in workflow
|
||||
assert "AWOOOI_DB_REQUIRED_CONNECTION_BUDGET" in workflow
|
||||
assert "api_http_concurrency_probe_passed" in workflow
|
||||
|
||||
Reference in New Issue
Block a user