issue #17 要求「每步 trace 可回放(谁/何模型/何工具/何审批)+ schema 冻结 + 测试」。 本仓已持久化事件流 + 任务谱系 + 每任务 usage(model_id) + 审批;本 PR 把它们规整为 统一、有序、可回放的审计记录并冻结 schema。 代码: - orchestrator/audit.py(新,纯模块,无 Redis/WS/FastAPI/模型):build_audit_trace( events, task_facts, approvals, lineage) 逐事件产审计记录(who/when/model_id/tool_count/ approval{id,decision}/result/lineage),audit_id 由序位确定(非随机,可字节级复现); replay(records) 产人读步骤行。无内容、无密钥、缺信号不伪造(model/tool 缺则 null)。 - orchestrator/main.py:build_audit_trace_for_run(装配器,从 list_events + 任务 usage + run.approvals 取数)+ 读接口 GET …/{id}/audit(三别名路由,复用既有鉴权)。 文档:docs/integration/audit-trace-schema.md → FROZEN v1:§3.1 回放装配、§5 冻结记录形; 诚实标注**有意排除**(prompt/代码原文、model 请求响应体刻意不留痕——无内容原则; 无 SK/MCP 工具层故无工具名谱系),按规则 #9 不伪造、不在本次扩展。 测试:scripts/test-audit-trace.py(纯模块 + 集成):逐步 who/model/tool/approval 重建、 result 归类、有序回放、**断言无 secret_ref/azkv/明文泄漏**;接入 CI。 影响范围:仅 agent_swarm(orchestrator 新增只读审计接口 + 纯模块 + 文档 + 测试 + CI)。 - Manager:新增只读 GET …/{id}/audit;不改回调/契约/计费/审批链。 - 密钥/审计:审计记录只含非内容元数据 + secret_ref 永不写入;归因按 user/channelId,不引入 tenant。 Refs #17 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
129 lines
4.1 KiB
YAML
129 lines
4.1 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: ["**"]
|
|
pull_request:
|
|
branches: ["**"]
|
|
|
|
jobs:
|
|
guardrails:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# Defense in depth: fail if secrets or heavy/generated dirs were ever committed.
|
|
- name: Block secrets & node_modules
|
|
run: |
|
|
if git ls-files | grep -E '(^|/)\.env($|\.)|(^|/)secrets/|\.pem$|\.key$|\.p12$|\.pfx$|(^|/)id_rsa$|(^|/)id_ed25519$'; then
|
|
echo "::error::Secret-like files are tracked — remove them and rotate any exposed credential."; exit 1
|
|
fi
|
|
if git ls-files | grep -E '(^|/)node_modules/'; then
|
|
echo "::error::node_modules is tracked — it must be gitignored."; exit 1
|
|
fi
|
|
|
|
- name: Required standards files present
|
|
run: |
|
|
for f in CLAUDE.md PROJECT_STANDARD.md README.md; do
|
|
test -f "$f" || { echo "::error::Missing required file: $f"; exit 1; }
|
|
done
|
|
|
|
tests:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.13"
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
pip install -r orchestrator/requirements.txt -r agent/requirements.txt
|
|
|
|
# Hermetic: in-memory store, planner forced offline by the tests — no model key needed.
|
|
- name: Manager contract test
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-runtime-contract.py
|
|
|
|
- name: Workflow mechanism smoke test
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-merge-smoke.py
|
|
|
|
- name: End-to-end workflow test
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-workflow-e2e.py
|
|
|
|
- name: Manager event-contract test
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-contract-events.py
|
|
|
|
- name: Audit / lineage trace (replayable) (#17)
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-audit-trace.py
|
|
|
|
- name: Benchmark metric formulas (v2.1)
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-benchmark-metrics.py
|
|
|
|
- name: Benchmark collector
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-benchmark-collector.py
|
|
|
|
- name: Baseline comparison
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-baseline-comparison.py
|
|
|
|
- name: Code sandbox (in-pod test runner)
|
|
run: python scripts/test-sandbox.py
|
|
|
|
- name: Quality instrumentation (Group B)
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-quality.py
|
|
|
|
- name: Decision-engine pheromone library (τ)
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-decision-engine.py
|
|
|
|
- name: Dispatch scoring formulas
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-dispatch-score.py
|
|
|
|
# --- decentralized swarm flow (the only flow; primitives are unconditional) ---
|
|
- name: Swarm seeder (#6)
|
|
run: python scripts/test-swarm-seed.py
|
|
|
|
- name: Swarm self-selection dispatch
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-swarm-dispatch.py
|
|
|
|
- name: Swarm autonomous task generation (#7)
|
|
env: { REDIS_FAKE: "1", AGENT_PROPOSAL_BUDGET: "3" }
|
|
run: python scripts/test-swarm-autonomous.py
|
|
|
|
- name: Swarm task competition (#8)
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-swarm-competition.py
|
|
|
|
- name: Swarm cross-review (#11)
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-swarm-cross-review.py
|
|
|
|
- name: Swarm convergence (#12)
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-swarm-convergence.py
|
|
|
|
- name: Swarm health guard
|
|
env: { REDIS_FAKE: "1" }
|
|
run: python scripts/test-swarm-guard.py
|
|
|
|
# Pure-module unit tests for the swarm primitives (formulas/policies, infra-free).
|
|
- name: Swarm primitive modules (unit)
|
|
env: { REDIS_FAKE: "1" }
|
|
run: |
|
|
python scripts/test-autonomous-tasks.py
|
|
python scripts/test-task-competition.py
|
|
python scripts/test-cross-review.py
|
|
python scripts/test-convergence.py
|