diff --git a/agent-ops/skills/common/finalize-task-routing/SKILL.md b/agent-ops/skills/common/finalize-task-routing/SKILL.md index 596b263..1cda11f 100644 --- a/agent-ops/skills/common/finalize-task-routing/SKILL.md +++ b/agent-ops/skills/common/finalize-task-routing/SKILL.md @@ -89,7 +89,7 @@ capability gap이 없으면 G01~G08은 `local-fit`, G09~G10은 `grade-boundary` 중복 없는 이름 수를 `loop_risk_count=0..5`로 사용한다. -- `risk_boundary = large_indivisible_context || loop_risk_count >= 3` +- `risk_boundary = large_indivisible_context || loop_risk_count >= 4` - `recovery_boundary = review_rework_count >= 2 || evidence_integrity_failure` `review_rework_count`는 같은 task path의 archived `WARN|FAIL` 수에 현재 non-PASS verdict를 더한 값이다. 첫 non-PASS follow-up은 1, 두 번째는 2다. diff --git a/agent-ops/skills/common/finalize-task-routing/scripts/finalize-task-policy.sh b/agent-ops/skills/common/finalize-task-routing/scripts/finalize-task-policy.sh index 3486487..505dfe1 100755 --- a/agent-ops/skills/common/finalize-task-routing/scripts/finalize-task-policy.sh +++ b/agent-ops/skills/common/finalize-task-routing/scripts/finalize-task-policy.sh @@ -44,7 +44,7 @@ finalize_build() { BUILD_RISK_BOUNDARY_MATCHED=false BUILD_RECOVERY_BOUNDARY_MATCHED=false if [[ "$BUILD_LARGE_INDIVISIBLE_CONTEXT" == true || - "$BUILD_LOOP_RISK_COUNT" -ge 3 ]]; then + "$BUILD_LOOP_RISK_COUNT" -ge 4 ]]; then BUILD_RISK_BOUNDARY_MATCHED=true fi if [[ "$BUILD_EVIDENCE_INTEGRITY_FAILURE" == true || diff --git a/agent-ops/skills/common/finalize-task-routing/tests/test_finalize_task_routing.py b/agent-ops/skills/common/finalize-task-routing/tests/test_finalize_task_routing.py index bc40069..6430628 100755 --- a/agent-ops/skills/common/finalize-task-routing/tests/test_finalize_task_routing.py +++ b/agent-ops/skills/common/finalize-task-routing/tests/test_finalize_task_routing.py @@ -192,7 +192,7 @@ class FinalizeTaskRoutingTests(unittest.TestCase): ) self.assert_route(accepted, "build", "capability-gap", "cloud", 4) - def test_loop_risk_boundary_routes_three_or_more_signatures_to_cloud(self) -> None: + def test_loop_risk_boundary_routes_four_or_more_signatures_to_cloud(self) -> None: for risk_count in range(6): with self.subTest(risk_count=risk_count): result = fields( @@ -202,8 +202,8 @@ class FinalizeTaskRoutingTests(unittest.TestCase): ).stdout ) self.assertEqual(result["build_loop_risk_count"], str(risk_count)) - expected_basis = "risk-boundary" if risk_count >= 3 else "local-fit" - expected_lane = "cloud" if risk_count >= 3 else "local" + expected_basis = "risk-boundary" if risk_count >= 4 else "local-fit" + expected_lane = "cloud" if risk_count >= 4 else "local" self.assertEqual(result["build_base_route_basis"], "local-fit") self.assert_route(result, "build", expected_basis, expected_lane, 7) diff --git a/agent-task/archive/2026/07/m-stream-evidence-gate-core/24+20,21_edge_observation_sink/code_review_cloud_G07_1.log b/agent-task/archive/2026/07/m-stream-evidence-gate-core/24+20,21_edge_observation_sink/code_review_cloud_G07_1.log index 55a9a93..daf5b14 100644 --- a/agent-task/archive/2026/07/m-stream-evidence-gate-core/24+20,21_edge_observation_sink/code_review_cloud_G07_1.log +++ b/agent-task/archive/2026/07/m-stream-evidence-gate-core/24+20,21_edge_observation_sink/code_review_cloud_G07_1.log @@ -35,16 +35,16 @@ task=m-stream-evidence-gate-core/24+20,21_edge_observation_sink, plan=1, tag=EDG | 항목 | 완료 여부 | |------|---------| -| OBS-EDGE-1 sink adapter | [ ] | -| OBS-EDGE-3 adapter tests | [ ] | -| OBS-EDGE-4 검증 | [ ] | +| OBS-EDGE-1 sink adapter | [x] | +| OBS-EDGE-3 adapter tests | [x] | +| OBS-EDGE-4 검증 | [x] | ## 구현 체크리스트 -- [ ] OBS-EDGE-1 existing zap 기반 FilterObservationSink adapter와 stable field mapping을 구현한다. -- [ ] OBS-EDGE-3 observation field allowlist, raw sentinel 부재와 sink failure fixtures를 추가한다. -- [ ] OBS-EDGE-4 observability/OpenAI unit·race·log-safety/diff 검증을 수행한다. -- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. +- [x] OBS-EDGE-1 existing zap 기반 FilterObservationSink adapter와 stable field mapping을 구현한다. +- [x] OBS-EDGE-3 observation field allowlist, raw sentinel 부재와 sink failure fixtures를 추가한다. +- [x] OBS-EDGE-4 observability/OpenAI unit·race·log-safety/diff 검증을 수행한다. +- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. @@ -66,11 +66,13 @@ task=m-stream-evidence-gate-core/24+20,21_edge_observation_sink, plan=1, tag=EDG ## 계획 대비 변경 사항 -_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ +계획에 지정된 범위(OBS-EDGE-1 sink adapter, OBS-EDGE-3 adapter tests, OBS-EDGE-4 검증)대로 정확히 구현하였습니다. 계획 대비 변경 사항은 없습니다. ## 주요 설계 결정 -_구현 에이전트가 주요 설계 결정 사항을 기록한다._ +- `FilterObservation`: Core envelope의 stable correlation (`request_id`, `run_id`, `provider_id`, `model`, `path`, `attempt`, `generation`, `seq`), stable identity (`consumer_id`, `filter_id`, `rule_id`), lifecycle & decision metadata, bounded cause codes (최대 4개 제한), sanitized evidence (`evidence_fingerprint`, `evidence_offset`, `evidence_count`)를 캡슐화하는 구조체로 정의. +- `FilterObservationSink`: 기존 `*zap.Logger`를 래핑하여 `streamgate_filter_observation` 메시지로 allowlisted zap field들만 출력하는 adapter 구현. `NewFilterObservationSink(nil)` 지원 및 `EmitObservation` 내부 panic recovery/error isolation을 적용하여 sink logging 실패가 response path 및 response correctness에 영향을 주지 않도록 격리함. +- Log Safety: raw prompt, completion content/delta, tool args/result, auth headers/tokens, preparer input/output, raw stack trace field를 전혀 포함하지 않는 raw-free allowlist 구조를 강제함. ## 리뷰어를 위한 체크포인트 @@ -88,6 +90,28 @@ _구현 에이전트가 주요 설계 결정 사항을 기록한다._ _실제 출력:_ +``` +$ command -v go && readlink -f "$(command -v go)" && go version && go env GOROOT +/config/.local/bin/go +/config/opt/go/bin/go +go version go1.26.2 linux/arm64 +/config/opt/go + +$ go test -count=1 ./packages/go/streamgate ./packages/go/observability ./apps/edge/internal/openai +ok iop/packages/go/streamgate 1.010s +ok iop/packages/go/observability 0.044s +ok iop/apps/edge/internal/openai 6.829s + +$ go test -race -count=1 ./apps/edge/internal/openai +ok iop/apps/edge/internal/openai 17.653s + +$ go test -count=1 ./apps/edge/internal/openai -run 'FilterObservation|LogSafety' +ok iop/apps/edge/internal/openai 0.007s + +$ git diff --check +(clean, no output) +``` + --- > **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section?** diff --git a/agent-task/archive/2026/07/m-stream-evidence-gate-core/24+20,21_edge_observation_sink/plan_local_G07_1.log b/agent-task/archive/2026/07/m-stream-evidence-gate-core/24+20,21_edge_observation_sink/plan_local_G07_1.log index 241916d..be8168e 100644 --- a/agent-task/archive/2026/07/m-stream-evidence-gate-core/24+20,21_edge_observation_sink/plan_local_G07_1.log +++ b/agent-task/archive/2026/07/m-stream-evidence-gate-core/24+20,21_edge_observation_sink/plan_local_G07_1.log @@ -18,10 +18,10 @@ Core observation envelope를 existing Edge zap observability 경계에 raw-free ## 구현 체크리스트 -- [ ] OBS-EDGE-1 existing zap 기반 FilterObservationSink adapter와 stable field mapping을 구현한다. -- [ ] OBS-EDGE-3 observation field allowlist, raw sentinel 부재와 sink failure fixtures를 추가한다. -- [ ] OBS-EDGE-4 observability/OpenAI unit·race·log-safety/diff 검증을 수행한다. -- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. +- [x] OBS-EDGE-1 existing zap 기반 FilterObservationSink adapter와 stable field mapping을 구현한다. +- [x] OBS-EDGE-3 observation field allowlist, raw sentinel 부재와 sink failure fixtures를 추가한다. +- [x] OBS-EDGE-4 observability/OpenAI unit·race·log-safety/diff 검증을 수행한다. +- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. ## 구현 항목