fix(ac-0024): address 4 blockers: NUL byte in C identity, instance_key isolation, clear_warned gate, production wiring

Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-08-26 00:20:09 +00:00
committed by GitHub
co-authored by genichin
parent 153a563f6d
commit f1864a6aa8
6 changed files with 162 additions and 33 deletions
+50 -28
View File
@@ -707,6 +707,9 @@ def _cmd_sync(args, cfg, confirm) -> int:
from trex_core.adapters.portfolio.reconcile_warning_store import (
PostgreSQLReconcileWarningStore,
)
from trex_core.adapters.portfolio.reconcile_notification_store import (
PostgreSQLReconcileNotificationStore,
)
from trex_core.application.reconciliation import sync_slot_to_broker
if not args.portfolio_id and not args.all:
@@ -745,6 +748,9 @@ def _cmd_sync(args, cfg, confirm) -> int:
return _broker_read_failure(exc, args.json)
warn_store = PostgreSQLReconcileWarningStore(cfg.dsn)
notification_store = PostgreSQLReconcileNotificationStore(cfg.dsn)
# req-0007 / ac-0024: alarm emitter for resolved notifications.
alarm_emitter_sync, _alarm_transport_sync = _default_alarm_emitter(cfg)
# Build slot_repo + slot_service
from trex_core.adapters.persistence.postgresql import PostgreSQLSlotRepository
@@ -789,22 +795,27 @@ def _cmd_sync(args, cfg, confirm) -> int:
results = []
exit_code = 0
for sid in slot_ids:
res = sync_slot_to_broker(
slot_id=sid,
slot_repo=slot_repo,
slot_service=slot_service,
broker=broker_port,
instance_key=instance,
warn_store=warn_store,
cost_basis_port=cost_basis_port,
dry_run=dry_run,
)
results.append(res)
# A skipped result can still be a fail-closed live error (REQ-123).
# Do not let the no-write marker hide a failed sync from automation.
if res.get("error"):
exit_code = 1
try:
for sid in slot_ids:
res = sync_slot_to_broker(
slot_id=sid,
slot_repo=slot_repo,
slot_service=slot_service,
broker=broker_port,
instance_key=instance,
warn_store=warn_store,
cost_basis_port=cost_basis_port,
dry_run=dry_run,
alarm_emitter=alarm_emitter_sync,
notification_store=notification_store,
)
results.append(res)
# A skipped result can still be a fail-closed live error (REQ-123).
# Do not let the no-write marker hide a failed sync from automation.
if res.get("error"):
exit_code = 1
finally:
_alarm_transport_sync.close()
if args.json:
print(_json.dumps({"instance": instance, "dry_run": dry_run, "results": results},
@@ -850,6 +861,9 @@ def _cmd_verify(args, cfg) -> int:
from trex_core.adapters.portfolio.reconcile_warning_store import (
PostgreSQLReconcileWarningStore,
)
from trex_core.adapters.portfolio.reconcile_notification_store import (
PostgreSQLReconcileNotificationStore,
)
from trex_core.application.portfolio import SnapshotStore
from trex_core.application.reconciliation import verify_slot_reconcile
@@ -867,6 +881,9 @@ def _cmd_verify(args, cfg) -> int:
return _broker_read_failure(exc, args.json)
warn_store = PostgreSQLReconcileWarningStore(cfg.dsn)
notification_store = PostgreSQLReconcileNotificationStore(cfg.dsn)
# req-0007 / ac-0024: alarm emitter for resolved notifications.
alarm_emitter_verify, _alarm_transport_verify = _default_alarm_emitter(cfg)
slot_repo = PostgreSQLSlotRepository(cfg.dsn)
# Build a minimal snapshot store (we only need asset_quantity for C-case check).
@@ -909,18 +926,23 @@ def _cmd_verify(args, cfg) -> int:
results = []
exit_code = 0
for pid in target_pids:
res = verify_slot_reconcile(
portfolio_id=pid,
store=store,
broker=broker_port,
slot_repo=slot_repo,
instance_key=instance,
warn_store=warn_store,
)
results.append(res)
if res["result"] == "rejected":
exit_code = 1
try:
for pid in target_pids:
res = verify_slot_reconcile(
portfolio_id=pid,
store=store,
broker=broker_port,
slot_repo=slot_repo,
instance_key=instance,
warn_store=warn_store,
alarm_emitter=alarm_emitter_verify,
notification_store=notification_store,
)
results.append(res)
if res["result"] == "rejected":
exit_code = 1
finally:
_alarm_transport_verify.close()
if args.json:
print(_json.dumps({"instance": instance, "results": results},