Changelog
NexusCore のプロジェクト固有変更履歴。 形式は Keep a Changelog に準拠。
[2026-09-04] - 読む系tools 3種実装(Phase 1 Task 11)
Added
- 読む系tools 3種(
src/nexuscore/harness/tools/read.py):read_file/list_dir/search_text・テスト7件(harness計57件中・1件は本変更と無関係の既存環境依存失敗=diagnosticsのサブプロセスPYTHONPATH問題・先行存在確認済み) ToolResultdataclass新設(round7修正条項①):read_fileが1MB超過時にToolResult(status="too_large", size, allowed_max)を返す(plan本文のValueError送出を修正条項が上書き・fail-soft継続・Task 17/20のnot_found/ambiguous/would_exceed_limitも本型に統一予定)list_dirdeny_paths事前フィルタ(round7修正条項②): deny_paths一致エントリをLLMに見せる前に隠蔽・照合はtool_gateと同一セマンティクス(glob×normpath+ファイル名単体)・非list型は全隠蔽(fail-closed・tool_gate deny-all相当)tool_policy.yaml初期版(読む系3道具=allow・provider_priority/provider_insecure_default)
[2026-09-01] - G1陽性対照実験完走 + deny_paths fail-open修正
Fixed
deny_paths非list型を破損扱いで deny-all(境界①・L438): 文字列deny_paths: 'denied'が1文字ずつfnmatchされ保護が無効化される(=fail-open)実測バグをisinstance(deny_paths, list)ガードで構造的に排除(非listはDENY+reason付与)
Added
- G1境界テスト5件(deny_paths非list deny-all / 0バイトポリシー deny-all / 略記文字列conf deny / mock複数tools先頭選択 /
_flush例外伝播)→ harness計50件 PASSED - ミューテーションG1陽性対照実験完走: baseline中央値1.22s(n=5・分散+44.3%<50%閾値)・手動パッチ変異5件(M1〜M5)が境界テスト全てkill+リバース検証全pass=陽性判定(事前固定基準「3件以上・fail-open系1件以上」を達成)
Notes
- 変異テスト詳細は obsidian-ssot
01_DECISIONS/NexusCore/2026-09-01_ミューテーションG1陽性対照実験完走.md・境界対応表00_SYSTEM/マルチLLMレビュー/2026-09-01_ミューテーション導入判断レビュー/g1_mutation_table.md
[2026-09-01] - ToolGate.evaluate引数改名(args→tool_args・ミューテーション対応)
Changed
ToolGate.evaluateの仮引数argsをtool_argsに改名: mutmut 3.5.0 が生成するラッパーが内部変数args = []を作り仮引数と衝突し、クリーン(変異なし)状態で引数辞書が空リスト化する実測バグへの対処(sentaku C案確定・キーワード専用引数のため spec §4 の契約は不変・テスト15call site更新)- テスト45件 PASSED・mutmut再実行で clean test 通過を確認(G0: 106ミュータント生成/G3: 26.9秒・通常実行の約10.8倍)
Notes
- mutmut生存ミュータント39件はトリアージ保留(サンプル: 初期値dead store等の等価ミュータント+
conf非dictガードの未テスト=P2起票済み境界③と一致)
[2026-09-01] - Task 10 push後3機レビュー対応(セキュリティ欠陥3件修正)
Fixed
- ネストされたargsのdeny_paths回避(Gemini critical):
args.values()の浅いスキャンでは{"paths": ["denied1.txt"]}のようなlist/dict内部の文字列が検査対象外になり deny を回避可能だった。_iter_arg_strings()で再帰列挙に修正 ../トラバーサルのパターンマッチ回避(Gemini high):src/../.git/HEADが'.git/**'パターンに一致せず回避可能だった。os.path.normpath()で正規化してからマッチUnicodeDecodeError未捕捉(両機指摘): 破損バイト列のポリシーで__init__が例外送出=fail-closed崩れ。捕捉に追加- FIFO等特殊ファイルでの無限ブロック(Gemini fail条件):
is_file()事前検証を追加し、特殊ファイルは破損扱いで fail-closed tools: nullで_loaded=Trueになる不整合(MiniMax high+Gemini med統合): toolsセクションの構造検証を追加し破損扱いに。非dictポリシー時の「コメントと実装の乖離」も解消
Changed
- deny reason にヒットしたパス値を含め機械可読prefix化(
ask required but channel unavailable等)・deny_paths優先順位(deny最強)をdocstring明記・load_policy戻り値をdict[str, Any]に強化
Added
- テスト5件追加(ネストdeny/トラバーサル正規化/FIFO fail-closed/デコード破損/tools null)→ harness計45件 PASSED
- レビュー正典: obsidian-ssot
00_SYSTEM/マルチLLMレビュー/2026-09-01_Task10-ToolGateレビュー/(MiniMax 13+Gemini 5・OpenRouterは2回502で2機統合)
保留(Phase 2以降)
- YAML重複キー検出(後勝ちの危険性指摘)・ツールスキーマ由来のpath引数特定(過剰拒否対策)・askタイムアウトの本体実装(ループ側)・判定logger
[2026-09-01] - エージェントハーネス Phase 1 Task 10(ToolGate fail-closed + policy loader)
Added
src/nexuscore/harness/tool_gate.py: 権限ゲートToolGate(spec §4)。道具1回ごと個別判定(束ね承認不可)・Mode(StrEnum: allow/ask/deny)+GateDecision(mode/reason)。deny_paths(fnmatch glob)をdefaultより先に評価・未登録tool=deny(保守側既定)・ask_supported=False時はdeny(Phase 1に確認チャネル無し→書く系はdeny)src/nexuscore/harness/config.py:load_policy()— tool_policy.yamlローダ(非dictは{"tools": {}}へ正規化・例外は握りつぶさず上位へ)- テスト追加:
tests/harness/test_tool_gate.py9件 → harness計40件 PASSED
Fixed
- plan雛形のfail-closed穴: 雛形は
FileNotFoundErrorのみcatchで、YAML構文破損時にyaml.YAMLErrorが素通りし(除句にyaml import無しのNameErrorも潜在)非dictポリシーでクラッシュ=fail-open相当。破損判定を「ローダ結果の構造検証+広範catch(FileNotFoundError/yaml.YAMLError/OSError)」に統一 - plan雛形テストの自己矛盾: 雛形テストは
ask_supported=FalseでASKを期待するが雛形実装・spec §4(askタイムアウト=deny)の方向はDENYが正。テストをask_supported=Trueでの独立性検証に修正
Notes
- 検証網羅区分: 正常系4件(個別判定/deny_paths/読むallow/ask対応時ASK)・境界1件(未登録tool=deny)・異常系4件(ポリシ不在/YAML破損/非dict/ask非対応)
- 判定のrunイベントログ記録(spec §4)はループ側責務として本クラスでは行わない(Phase 1 MVP・YAGNI)
[2026-09-01] - エージェントハーネス Phase 1 Task 9(LocalLLM用tool_callダミー)
Added
src/nexuscore/harness/mock_provider.py:LocalToolCallDummyLLM— LocalLLMを内包するテスト専用ラッパー。先頭tool名のダミーInternalToolCall(args空dict・呼び出し側で補完する設計)を返す。実HTTPは一切叩かずlast_call_modeは常にstub。capability tableには一切触れない(plan 1959行「mock実行時はcapability更新禁止」・テストで固定済み)- テスト追加:
tests/harness/test_mock_provider.py6件 → harness計31件 PASSED
Notes
- plan雛形からの変更点: ①雛形はtoolあり応答で
content: Noneを返すがToolCallingMixinの戻り値契約はcontent: strのため""に修正 ②雛形の_innerが未使用でwrapが形骸化するためmodel_name/last_call_modeを委譲する契約を追加 - 検証網羅区分: 正常系3件(tool_call返却/契約準拠/wrap委譲)・境界1件(tools空)・異常系2件(オフラインstub保証/capability不触)
[2026-08-31] - エージェントハーネス Phase 1 Task 8(capability table実装)
Added
src/nexuscore/harness/capability.py: provider単位のcapability table(CapabilityTable)。spec §10 のスキーマ{supports_tool_calling, last_verified_at, schema_version}を JSON で原子的書き込み(temp+rename)永続化。パスはNEXUSCORE_CAPABILITY_PATH環境変数で上書き可(既定artifacts/harness/capability.json)- 更新契機3系統API: ①Phase 0バルク書込=
update_many()②Mixin初期化時/③明示的refresh=set()。supports_tool_calling(provider_id)は計測済みならbool・未計測なら None(False と区別・fail-closed側) - テスト追加:
tests/harness/test_capability.py7件(スキーマ永続化 / tz-aware ISO / 再構築 / 未計測None / バルク / 上書き / .tmp残存なし)→ harness 計22件 PASSED
Notes
- plan雛形からの変更点: 雛形に無い
update_many()を追加(雛形の set() のみでは spec §10 の「更新契機3系統」契約を満たせないため)・utcnow()(Python 3.12 非推奨)をnow(dt.UTC)に変更 - Mixin初期化時/refresh 系統の実際の配線(ToolCallingMixin 側からの呼び出し)は後続タスク(ToolGate/ループ統合)で実装
- 実装中に Write 出力が途中で崩壊し汚染ファイルを書き込む事故が1回発生 → Read実体確認後、分割書込で再生成して復旧(テスト7件で機械検証済み)
[2026-08-31] - エージェントハーネス Phase 1 Task 7(残り3プロバイダー Mix-in)
Added
OpenAICompatLLMMix-in:class OpenAICompatLLM(ToolCallingMixin, BaseLLM)— GLM/MiniMax/DeepSeek/Moonshot の基底。adapter は OpenAILLM と同じ構造(OpenAI互換のため identity 変換)。HTTP 経路は既存 self.session/api_path を再利用、stub 時は固定 echo tool_call 応答AnthropicLLMMix-in:class AnthropicLLM(ToolCallingMixin, BaseLLM)— Anthropic 専用 adapter。messages先頭の system ロールをsystemフィールドに分離、toolsは{name, description, input_schema}形式に変換。content配列のtool_use/textブロックを分離抽出。/v1/messagesにPOST、stub時は固定 tool_use 応答GeminiLLMMix-in:class GeminiLLM(ToolCallingMixin, BaseLLM)— Gemini 専用 adapter。generateContent形式のcontents[].parts[]↔ OpenAI messages、tools[].functionDeclarations[]↔ tools を相互変換。HTTP直接叩き(/v1beta/models/{model}:generateContent?key={api_key})、既存SDK経路(execute())とは別経路- テスト追加:
tests/harness/test_tool_calling_mixin.pyにパラメタライズド6ケース追加(OpenAICompat/Anthropic/Gemini × complete_with_tools stub / MRO確認)→ 計14件 PASSED
Notes
- 各adapterは Task 6 の防御ガード(choices空 / message不在 / tool_call.function.name不在 / candidates空 / parts不在 / name不在)を反映済み
- 既存tests/llm/ 638 passed・5 errors は
pytest-mock未導入による事前壊れ(5a0140dbHEAD でも同じ失敗を確認済み)→ Task 7 由来ではない新規回帰ゼロ tests/llm/logs/はNexusCoreの追跡外ディレクトリ(以前からの未追跡物・触らない)
[2026-08-31] - セキュリティレビュー対応(Task 6 push後の自動レビュー指摘)
Changed
_call_http_toolの real_calls 経路をexecute_real_or_fallbackで包む: HIGH指摘対応。r.raise_for_status()+r.json()の生例外を投げず、C5(silent-fallback)対策のフォールバック経路とNEXUSCORE_ALLOW_STUB_FALLBACK互換性を回復_adapt_response_native_to_internalの防御ガード: MEDIUM指摘対応。choices空 /message不在 /tool_call.function.name不在をKeyError/AttributeErrorでクラッシュさせず、空tool_callsを返す安全側に倒す- テスト追加:
tests/harness/test_tool_calling_mixin.pyに4ケース追加(empty_choices / missing_message / tool_call_without_function_name / stub_path_unchanged)→ 計8件 PASSED
Security
- finding 1 (HIGH):
_call_http_toolの例外処理をexecute_real_or_fallbackで統合 - finding 2 (MEDIUM):
_adapt_response_native_to_internalの防御ガード追加
[2026-08-31] - エージェントハーネス Phase 1 Task 6(OpenAILLM への Mix-in・template provider)
Added
- Mix-in 適用:
src/nexuscore/llm/providers/openai_provider.py:11のclass OpenAILLM(BaseLLM)をclass OpenAILLM(ToolCallingMixin, BaseLLM)に変更 - 3差分フック実装(OpenAILLM):
_adapt_request_openai_to_native:{model, messages, tools, **kwargs}を返すだけの identity(OpenAI ネイティブ=OpenAI 形式のため変換不要)_adapt_response_native_to_internal: OpenAI chat completions のchoices[0].message.tool_callsをInternalToolCall.from_openaiで中立表現に変換_call_http_tool: 既存self.session/ Azure設定 /self.real_callsを再利用する HTTP 経路。stub モードでは固定の echo tool_call を返す(Task 9 の force_429 と区別)
- テスト:
tests/harness/test_tool_calling_mixin.py4件 — 必須3キー / InternalToolCall変換 / MRO確認 / adapt_request
Notes
- 既存テスト(harness/以外)は Task 5 完了直後の HEAD (
71c945ed) で同じく6件失敗していたことを実測で確認(fakeredis/python-patch/gradioの依存未導入・debugger_agent系ロジック)→ Task 6 による新規回帰ゼロ - Phase 0 撤退判定(Task 4)で承認済み・Task 6 着手OK
[2026-08-31] - エージェントハーネス Phase 1 Task 5(ToolCallingMixinスケルトン)
Added
- ToolCallingMixin:
src/nexuscore/harness/tool_calling_mixin.py— OpenAI/Anthropic/Gemini 3形式の tool calling 差分を吸収する Mixin のスケルトンInternalToolCall: 内部中立表現(name/args/id・__slots__制限)。from_openai/from_anthropic/from_geminiの3変換 +to_openaiの書き出し_sanitize_id: spec §10 の正規化(^[a-zA-Z0-9_-]{1,64}$)— 不正文字除去・64字カットToolCallingMixin.complete_with_tools: OpenAI 形式 messages/tools →{content, tool_calls, usage}の公開 API- 3フック
_adapt_request_openai_to_native/_call_http_tool/_adapt_response_native_to_internalはNotImplementedErrorのまま Task 6/7 で provider 別 override する設計
Notes
- Phase 0 撤退判定(Task 4)で「全項目非該当」を別セッションで確定後に着手。詳細:
01_DECISIONS/NexusCore/2026-08-31_phase0_failfast判定.md(SSOT) - 既存
tests/harness/(diagnostics テスト1件)の回帰なし
[2026-08-31] - orchestratorパッケージ利用実態棚卸し(デッドコード判定)
Added
- 棚卸しレポート:
docs/refactoring/orchestrator利用実態棚卸し-2026-08-31.md—src/nexuscore/orchestrator/(1373行・テスト15ファイル)の全参照マップと3択判断
Notes
- 判定: ① 統合維持(デッドコードではない)。REST API(
POST /api/v1/runs等)経由で uvicorn 本体から全モジュール到達可能・src内孤立モジュール0件(grep実測)。CLI(main_cli)・webapp経路は本パッケージ不使用 - テスト実測: tests/orchestrator 111 passed / 7 skipped(main_cli配線の未実装skip)・tests/api run_view 11 passed / 1 xfailed
- skip 2件が stale monkeypatch(
_load_guardian_credentials廃止追従未実施)— フォロー候補としてレポートに記録
[2026-08-31] - エージェントハーネス Phase 0(fail-fast spike)実施
Added
- diagnostics CLI:
src/nexuscore/harness/diagnostics.py— mro / override_check / factory_pos / retry_diff / tool_echo / ack の6サブコマンド(計測結果はartifacts/phase0/・gitignore対象) - Phase 0判定基準:
artifacts/phase0/CRITERIA.md(撤退判定基準の凍結)+CHECKLIST.template.md - テスト:
tests/harness/test_diagnostics.py
Changed
- plan雛形コードのバグ4件を修正して実装(argparseサブパーサー二重登録 /
--out無視 / override_checkの継承メソッド誤拾い / retry_diffの共通HTTP層〔http_client.py urllib3 Retry〕見落とし) tool_echoは実HTTP呼出を試行し結果をありのまま記録する方式(ok捏造なし)
Notes
- 計測結果: 全項目で撤退基準非該当(MRO全OK・mixin_overlap=[]・実効リトライ欠落0・echo往復 glm/minimax/openrouter/deepseek の4種成功・openai=429レート制限で未確認・moonshot=APIキーなし)
- Task 4(撤退判定)は別セッション+ふくけい承認で実施(Phase 1着手は未確定)
[2026-08-30] - エージェントハーネス設計フェーズ完遂(spec + 実装計画)
Added
- 設計spec:
docs/superpowers/specs/2026-08-30-nexuscore-agent-harness-design.md— Claude Codeのようなエージェントハーネス(tool callingループ+権限ゲート+サーキットブレーカ)を自前実装する設計。D案(フォーマット別Mixin共用方式・4クラスへMix-in)+MVP/強化層の2階層化 - 実装計画:
docs/superpowers/plans/2026-08-30-nexuscore-agent-harness.md— Phase 0〜5・27タスクのTDD構成計画(Phase 0 fail-fast spike→読む→書く→撃つ→Web UI→dogfooding) - レビュー: multi-llm-review triple 7ラウンド計132件の指摘を統合(経緯: obsidian-ssot
00_SYSTEM/マルチLLMレビュー/2026-08-30_NexusCoreハーネス方式選定/)
Notes
- 本エントリは設計フェーズのみ(実装は未着手・Phase 0から次セッションで開始)
- 既存コードへの変更はゼロ(spec/plan/docs追加のみ)
[2026-08-29] - A群消化: 脆弱性4件解消・CI保護強化・テストの完全オフライン化
Security
- 既知脆弱性4件を解消(
pip-audit実走で検出・修正後はNo known vulnerabilities found):Flask-CORS 4.0.2 → >=6.0.0(PYSEC-2026-1383/-1384/-1385)・pytest 7.4.4 → >=9.0.3(PYSEC-2026-1845・9.1.1で5,029テスト緑を確認) - 未使用依存5件を削除: torch / tensorflow / SpeechRecognition / websockets / psutil(AST実測で実import 0件)。pydub/standard-aifc は維持 — gradio が import 時に pydub を要求する実行時推移依存のため(コレクションエラー4件で実測・「直接import 0件」でも削除不可の反証実績)
- pip-audit を CI ゲート化(
sca-scanjob 新設・requirements.txt 対象) - gitleaks を独立 workflow 化(
secret-scan.yml): push/PR=差分走査 + 週次 schedule(月曜 03:23 UTC)=全履歴走査で「push時は差分のみ」との宣言乖離を解消 vscode-extension/node_modules/3,075ファイルを追跡解除(package-lock.json は追跡維持)・孤児 submodule gitlink 削除(tree_sitter_languages/tree-sitter-python・CI post-checkout の exit 128 warning 解消)
Fixed
utils/tree_sitter/_analyzer.py:238のログ書式バグ(%.1%%→%.1f%%・2026-05-12混入の潜在バグ。pytest 7 は握りつぶし pytest 9 は致命化)- networkx を明示依存に追加:
analyzer/graph_builder.pyの直接importが torch の推移依存で暗黙供給されており、torch 削除で CI 新規環境のみ収集エラー3件(2026-08-30 実測)。fresh venv からの再インストールE2Eで 5,027 passed を確認 - テスト中の実ネットワーク呼び出しを禁止:
LLMRouter.__init__の_detect_and_update_modelsが OpenAI/Gemini models.list に実HTTPSリクエストを送っていた(cProfile 実測: 単一テストで28リクエスト・20.5秒)。既存スイッチNEXUS_DISABLE_MODEL_DETECTIONを conftest で有効化 → スイート 876s → 149.68s(約6倍高速化)かつネットワーク非依存の決定的実行に
Changed
- Python バージョン宣言を3.12へ統一:
.python-version3.11.9 → 3.12.3・ci.yml security-scan job 3.11 → 3.12 - Safe Tests workflow を削除: ci.yml test job と同一スイートの重複実行・独自 env 変数(
NEXUSCORE_DISABLE_REAL_LLM等)はコード参照ゼロの実測に基づく - pytest 9.1.1 移行(7.4.4 → 9.1.1): 5029 passed / 187 skipped / 26 xfailed / 12 xpassed
検証証跡(全て生 exit code 0)
pytest -q: 5029 passed, 187 skipped, 9 deselected, 26 xfailed, 12 xpassed in 149.68smypy src/: Success(255ファイル)・ruff check src/ tests/: All checks passedpip-audit -r requirements.txt: No known vulnerabilities found- 起動スモーク
python main_cli.py --help: usage 出力
[2026-08-29] - 包括レビュー(差分・コード変更なし)
Audit(レビューのみ・本エントリによるコード変更は無し)
- 2026-08-12 包括レビューの10件を実測で答え合わせ。完全解消1件(生成物90+件のgit追跡解除・
src/sandbox_logstracked=0)・部分解消3件(CI静的解析配線/mypy.iniの3.12是正/tests→app/直import 20→0)・未解消6件。循環依存 5組→5組・api → webapp28→28 と同値、README は乖離が拡大 - 品質ゲート実走:
ruff check src/ tests/exit 0 /mypy src/exit 0(255ファイル)/pytest -q5029 passed, 187 skipped, 27 xfailed, 11 xpassed exit 0(123.19s)
Security(要対応・未修正)
pip-audit -r requirements.txtで既知脆弱性4件を検出(exit 1):flask-cors 4.0.2(PYSEC-2026-1383 / -1384 / -1385 → Fix 6.0.0)・pytest 7.4.4(PYSEC-2026-1845 → Fix 9.0.3)。requirements.txtの上限Flask-CORS<5.0.0/pytest<8.0.0が修正版の取り込みをブロックしている。pip-auditはrequirements-dev.txtに導入済みだが CI に未配線(semgrepdetect-secretsも同様)
検出された未整理(新規・前回未検出)
vscode-extension/node_modules/が 3,075ファイル / 442,980 LOC git追跡下(自作の拡張コードは10ファイル / 3,598 LOC のみ)。logs/75ファイル / 34,586 LOC も追跡下- CI の ruff ジョブは
src/ tests/のみを対象とし、tools/(56py)scripts/dev_tools/app/database/main_cli.pyは未 lint → ruff 1,160件(660件は--fix可)。複雑度ワーストもtools/に集中(code_export_for_ai.py:569CC=45・stit_branch.py:640 main341行) - Python バージョン宣言が4箇所で不一致(pyproject
>=3.12/.python-version3.11.9 /ci.yml:273.11 /safe-tests.yml:423.11) - README の陳腐化:
src/nexuscore/audio/は不在・「5,465テスト」主張(4箇所)に対し実測収集 5,237・「84.69%」に対しcoverage.xmlは 84.99%(かつ 2026-07-08 生成で44コミット前)・「Pylint 8.0+」だがpylintの宣言は0件 - 詳細記録:
obsidian-ssot/01_DECISIONS/NexusCore/2026-08-29_包括レビュー差分-前回10件消化状況と新規3件.md
[2026-08-21] - FKB真因判別・案1: Debugger指示文の候補解化(アンカリング緩和)
Changed
agents/debugger_agent.py: KBヒット時のLLM指示文を命令形Apply the following patternから「候補解提示+真因一致確認の要求」(同一シグネチャでも真因は異なり得る旨・不一致時は棄却して通常分析)へ変更。Zenn記事への realbios氏コメント(シグネチャ既知≠真因既知・知識の粒度を「答え」でなく「切り方」に)の指摘がdebugger_agent.py:146-148の命令形指示とFKB実データ102件のsignature→solution直接対応で実際に当てはまることの検証結果(2026-08-19)を受けた第一段階対応。案2(FKBスキーマへcandidate_causes[]+discrimination[]判別プローブ追加)は後続- テスト:
tests/agents/test_debugger_agent.pyにtest_kb_instruction_treats_solution_as_candidate追加(candidate/verify 含有・命令形文言の不在を検証)
[2026-08-18] - C3 Plan2: Orchestrator内部冪等性(phaseチェックポイント+LLM結果キャッシュ)
Added(C3 Plan2・マルチLLMレビュー+L3弁証論反映)
core/run_checkpoint.py: チェックポイント単一キーcheckpoint:{run_db_id}(1回SET=アトミック・schema_version・512KB超zlib圧縮)+run_phases_with_checkpoint()(完了phase skip・heartbeat_fn依存注入)+LLM結果キャッシュ(フルハッシュ・TTL24h)+timeout1s+60sサーキットブレーカorchestrator.py/orchestrator_helper.py: phaseループ委譲+heartbeat_fn経路貫通(CLI実行=run_db_id Noneは無効)_execute_task_via_npe: LLMキャッシュhit時guarded_llm_call skip(hit/missログ・NEXUSCORE_LLM_CACHE=0/NEXUSCORE_CHECKPOINT=0で無効化)celery_app.py: 実行ロックTTL 30s→600s+phase完了heartbeat(並走防止)・ロック失敗時は660s後retry(タスク消失防止)・不変条件LOCK_TTL<visibility_timeoutをCIテスト固定・SUCCESS時checkpointクリア- テスト環境では
NEXUSCORE_LLM_CACHE=0をconftestで既定設定(実Redis稼働環境でのテスト間キャッシュ衝突防止)
Fixed(マルチLLMレビュー MiniMax+Gemini 採用6件・2026-08-18)
run_checkpoint.py: 未知phase名のKeyErrorクラッシュ→警告+フル再実行に退化 / get_client接続プールをURL-keyedキャッシュ+atexitクロース / llm_cache_keyのmodel=Noneガード / OrchestratorContextをmodule-level import(テスタビリティ) / ブレーカのプロセスローカル性を明記celery_app.py: SUCCESS時checkpointクリアをcommit後(finally)へ移動(commit前クラッシュ→再配送フル再実行の窓縮小)+final_status早期初期化(空requirement早期returnでのUnboundLocalError→実行ロックリーク修正)+ ロック解放回帰テスト- レビュー詳細: obsidian-ssot 00_SYSTEM/マルチLLMレビュー/2026-08-18_C3Plan2実装レビュー/
[2026-08-18] - Safe Tests workflow赤修正(Redis service追加)
Fixed
nexuscore-safe-tests.yml: C3冪等性テスト(test_celery_job_state_machine3件)とtest_fastapi_project_runs.py::test_trigger_project_run_successが実Redis localhost:6379を参照するため、ci.ymlと同一のredis:7-alpineサービスコンテナを追加(2026-08-15のci.yml CI赤復旧時にsafe-tests側への追加が漏れていた・19連続赤の直近原因)
[2026-08-17] - nexuscore-bench Phase 0: 壁2/壁3解消+FKBフルループ実証
Fixed(学習ルートの本質バグ2件・nexuscore-bench検証で発見)
debugger_agent.py_generate_fixed_code: LLM応答全体をコードとみなす仕様を改め、```pythonフェンス優先でコード抽出(「説明文+コード」応答で説明文ごと書き込みSyntaxErrorになる事故を根本修正)debugger_agent.py: LLMがunified diff形式で回答した場合に元ソースへ適用してfixed codeを再構成(diff本文がそのままコードとして書き込まれる事故を修正)knowledge_curator_agent.py: サンドボックス検証失敗時にpytest出力tailをログ(観測フック・上記バグ特定の鍵)
Added(nexuscore-bench Phase 0・spec: obsidian-ssot 2026-08-17-nexuscore-bench-design.md v1.1)
- 壁2-A:
patch_applier.pyに削除行数上限ガード(max_delete_lines=20・SelfHealingConfig連携) - 壁2-B:
_guardian_helpers/ast_safety.py(削除適用後のAST安全検証+適用前スナップショットからのロールバック・reject時は人手承認フラグ) - 壁3: タスク単位LLBプロファイルenv上書き(
NEXUS_TASK_MODEL_<TASK>・例: DEBUG=gemini_secondary。カテゴリ単位envより優先・未設定で完全不変の後方互換) - FKB参照ログ:
knowledge_reference_logsテーブル+log_reference/query_references/get_id_by_signature(bench主指標の前提)+Alembic migration a7c3f91d5e02 - FKB運用: snapshot(全エントリJSON書出)+
disabled論理削除+scripts/fkb_ops.pyCLI(汚染スパイラル対策) scripts/verify_fkb_fullloop_real.py: フルループE2E検証(失敗→postmortem→curator→FKB保存→次タスク参照→修正成功)
Verified
- FKBフルループE2E: 4/4 (100%)(postmortem/debug=Gemini 3.1 Pro・curator=MiniMax・隔離sqlite)
- 全テスト回帰: 4,995 passed(ベースライン4,975+新規20件・回帰ゼロ)・ruff緑
- GLM現行ルーティングでは0/4(GLM 429連発+修正品質不足の実証データ→壁3再定義: 「出力パース堅牢性」が本質障壁の一つだった)
Fixed(mypy src/ 17エラー→0)
phase_runner_mixin.py: ホスト(Orchestrator)が提供するarchitect_agent/guardian_agent/constitutionを TYPE_CHECKING ブロックに型宣言(mixin契約の明文化・6エラー解消)。docstring の契約列挙も実態より古かったopenrouter_key.py×3:current_user.id(AuthenticatedUser に存在しない属性=実行時 AttributeError の潜在バグ)→get_user_id_from_auth()変換アダプタ経由に修正(_projects_runs.pyと同じパターン)guardian_agent.py:self.modelのor合成がstr | Noneになるのを条件式でstrに確定(空文字フォールバックの実挙動は不変)-
unified_analyzer.py:_save_analysis_cacheにself.cache is Noneガード追加+2ループ目の変数名衝突(file_hashの再代入で strNone 化)解消 unified_config.py:os.getenv("FLASK_SECRET_KEY", ... else None)が str 型フィールドに None を入れうる型違反を解消(本番未設定時 None→空文字=Flask が起動拒否・実挙動ほぼ不変)retry_utils.py: 新 mypy(1.20系)で不要になった stale なtype: ignore[arg-type]を除去mypy.ini:python_version 3.11→3.12是正(pyproject requires-python>=3.12)・api/archiveを exclude 追加(非現用コード・bandit/ruff と同じ除外方針)・未使用セクション(プリフィックス無し github_webhook)除去・UI層のattr-defined無効化(gradio の minor バージョン差でイベント属性型定義が変わるため: ローカル実証 6.13 vs CI解決 6.24 で Button.click 等が16エラー・他エラーコードは検査継続・commit 5168227e)
Added(CI)
- ci.yml test job に mypy ステップ(
mypy==1.20.2固定・mypy src/)を追加。依存未インストール環境では mypy 結果が変わる(pydantic 等の型情報が必要・空venv実測で32エラー)ため、フル依存インストール後の test job 内で実行する構成(別 job 化しない理由)
Verified
- mypy: Success: no issues found in 253 source files(python 3.12・archive 除外)
- 回帰: config+analyzer+api 622 passed / core 911 passed / guardian 3 passed・ruff src/tests 緑
[2026-08-15] - C6 Step2: ruff CI ジョブ追加・gitleaks 実効化
Added
- ci.yml に Lint (ruff) ジョブ(src/ + tests/ 範囲・ハードゲート)を追加。src/tests の ruff 緑(2026-08-14 達成・commit 327c4a18)を CI で永続担保。走査範囲は src/tests のみ(scripts=30件・tools=1070件の残存違反は P2 対応後に拡張)。
ruff>=0.15.0,<1.0.0(ローカル実測 0.15.12 に揃え・requirements-dev.txt 範囲内) - gitleaks を実効化:
continue-on-error: trueを除去し、検出で CI が赤になるよう変更(2026-08-05 導入以降の検出ゼロを確認済み)
Changed
- README の静的解析宣言を実態に更新: ruff(src/tests 全走査・CI必須ゲート)+ gitleaks(CI必須ゲート)・mypy は src/ 残17エラー解消後に CI 導入予定
[2026-08-15] - CI 赤化解消(GitPython 依存追加)
Fixed
- CI が 2026-08-01 以降全 run failure していた問題を解消(収集エラー2件+テスト失敗7件の計9件・CI赤の2週間で回帰が表面化せず潜んでいた):
src/nexuscore/agents/guardian_agent.py:8のimport git(GitPython)がrequirements.txtに未宣言で、CI(クリーン環境)でのみModuleNotFoundError: No module named 'git'により7テストファイルが収集エラー→全テスト未実行(exit 2)。ローカル.venvには入っていたため気づかず。requirements.txtに直接依存としてGitPython>=3.1.40,<4.0.0を追加(lock 側は既に gitpython==3.1.45)tree_sitter_checker.pyからCONFIG/TREE_SITTER_AVAILABLE/Styleの legacy re-export を復元: 2026-08-02 commit 8229ac0f(ruff F401 機械除去)がテストが利用する公開シンボルまで削除。AnalysisResultには# noqa: F401 — legacy re-export保護が付いていたのに CONFIG 群には付いていなかったのが直接原因。noqa 保護付きで復元_projects_runs.pyの関数内from fastapi import HTTPExceptionが未実行パスでUnboundLocalErrorになるバグを修正(module level import に統合)。project_not_found 時 404 でなく 500 を返していたcelery_app.py: タスク直接呼び出し(テスト)でself.request.idが None のまま Redis SET に渡りDataError: NoneTypeになるのを uuid フォールバックで修正(acquire/release 両方)test_external_api_smoke.py::test_post_run_with_api_key: 全os.getenvを “1” に上書きするパッチが C3 のtask_lock.get_redis()(REDIS_URL 読み取り)を壊し 500 になっていたのを、NEXUS_USE_CELERY のみ選択化+fakeredis 注入で修正(C3 追加以降の潜在不良)- ci.yml の test job に Redis service container(redis:7-alpine)を追加: C3 冪等性テストが実 Redis localhost:6379 を参照するため(CI環境固有の ConnectionError 3件+500 の解消)
[2026-08-15] - C5 残課題の完全テスト追加(T6/T7 retry境界・T9 FAILED集約)
Added
tests/agents/test_c5_retry_boundary.py(4件): 8/13実装の retry 境界を機械検証。T6=429 HTTPError が ModelRateLimitError に変換され max_retries=2 で計3回試行+1回目429→2回目成功の復帰 / T7=恒久失敗(5xx・permission denied)は unexpected 分類で1回のみ試行の即例外伝播。既存test_c5_exception_propagation.pyはpatch(HAS_RETRY, False)で retry 経路を回避しており、HAS_RETRY=True の実経路(retry_with_contextwrapper)は本ファイルが初カバーtests/core/test_c5_orchestrator_failed_aggregation.py(2件): T9=伝播例外で_log_orch_event(run_db_id, "orchestrator", "FAILED", ...)発火+再 raise+FINISHED未発火(誤成功なし)+メッセージに元エラー含有。呼出側のRun.status="FAILED"DB反映は既存tests/webapp/test_celery_app.pyが担保(役割分離)
Verified
- 新規6件: 6 passed(0.71s・retry backoff の sleep は monkeypatch で無効化)
- 回帰: tests/agents+core+llm で 2545 passed / 41 skipped / 0 failed(12分・
.venvpython使用。システムpythonでは gradio 未依存の3ファイルが収集エラーになるため venv 必須)
[2026-08-14] - ruff 既存違反 tests/ 残り50件→0件解消(L158・C6 CI保護完全化の前提)
Changed
- tests/ 配下25ファイル・50件のruff既存違反を解消(2026-08-12 src/完了の残・A+Dハイブリッド方針踏襲)
- F841(34件)・B007(2件)・E741(1件):
--unsafe-fixes --select F841,B007,E741で機械解消(F401除外で再エクスポート壊れ回避・前回教訓)。E741のl→lineは手動 - E731(4件): lambda→def 関数化(test_fallback ×3・test_authority_runner ×1)
- B017(3件): blind
Exceptionを具体例外化。frozen dataclass の setattr/delete はFrozenInstanceError(import追加)・decrypt の不正 ciphertext はInvalidTag(cryptography.exceptions・import追加・元々Exceptionで隠れていた正しい例外型を特定) - F401(2件)・F821(1件)・F811(1件)・B018(2件):
# noqaで保護。streamlit/tree_sitter は try/except による import 可用性チェック(正当)・test_server_execute.py は module-level skip 済み(archived Flask)・conftest は fixture 再エクスポート
Fixed
- test_authority_runner:896
test_uses_factory_over_globalの検証不全を修正: 元は「検証ゼロの式文」(or式・orchestrator.start は実装に存在しない)だった。state にnext_phase: "planning"を追加し、実在のrun_planning_phase呼び出しで factory優先を検証(factory呼ばれる・global呼ばれないを assert)。実装(resume.py factory選択)は正常・テスト側の実装乖離だった - test_imports:27 の属性アクセスは
pytest.raises(AttributeError)内の正当な検証(noqa保護)
Verified
ruff check tests/: All checks passed!(50→0件)・ruff check src/: 緑(回帰なし)- 修正8ファイル pytest: 227 passed / 0 failed(16 skipped・5 xfailed は既存)
- 残り赤は pre-existing(gradio/tree_sitter/Redis/Celery 依存・本タスク無関係)
[2026-08-13] - C5 silent stub-fallback 解消(E+α改・例外伝播)
Changed
llm/providers/base.pyexecute_real_or_fallback: real call 失敗時のreturn _stub_fallback_response(...)をNEXUSCORE_ALLOW_STUB_FALLBACKフラグ判定付きraiseに変更(フラグOFF=本番は例外・ON=従来stub)。openai/anthropic/gemini の3プロバイダがカバー(commit 762a4b9c)llm/providers/openai_compat.py: 429は従来通りraise(rate-limited)維持・それ以外のHTTPエラー/Exception を同フラグ判定raiseに変更。deepseek/glm/minimax/moonshot/openrouter の5プロバイダが継承で網羅agents/base_agent.pyexecute_llm_task: 例外時の{}/""握りつぶし(base_agent.py:163-174)をフラグ判定raiseに変更(α・commit c8b6472c)。7/30「案C破壊的(握りつぶされる)」懸念へ構造的回答・二次silent封鎖
Added
- 環境変数
NEXUSCORE_ALLOW_STUB_FALLBACK(デフォルトOFF=本番例外・=1で従来stubを統合テスト保護・spec §4.4) tests/llm/conftest.py・tests/agents/conftest.py・tests/api/test_issue_86_base_agent.py: autouse fixture で従来フォールバック挙動の後方互換(フラグON)tests/llm/test_stub_fallback_exception.py(T1/T2: 発生源のフラグOFFで例外・ONでstub)tests/agents/test_c5_exception_propagation.py(T5/T6/T7: αの直接検証・フラグOFFでraise・ONで{}/”“・real成功回帰)
Fixed
- C5(CRITICAL#5): LLM失敗時にstub文字列を黙って返し下流Coder/Plannerが正規出力と誤認する silent stub-fallback を解消。発生源(プロバイダ層)+ α(execute_llm_task 最終フォールバック)の2層で例外伝播→orchestrator 既存口(
run_full_project:197)で Run.status=FAILED 集約。7/30→8/5監査の再逆転(例外伝播)を完結
Verified
tests/llm: 645 passed(回帰ゼロ)・tests/agents: 982 passed・test_issue_86_base_agent: 11 passed- ruff/mypy 緑(変更ファイル)
- 残り赤7件は pre-existing(HTTPException 既存バグ・celery・tree_sitter・α無関係)
- spec:
docs/superpowers/specs/2026-08-12-c5-stub-fallback-exception-propagation-design.md
[2026-08-12] - ruff 既存違反解消 src/+tests/(L158・C6 CI保護の前提)
Changed
- ruff 既存違反 src/ 53件を解消: I001 import並び・UP 型アノテーション現代化・F541 空 f-string 等 safe-fix 30件 + F821/F811/B904/F401/F841 手動修正
webapp/orchestrator_helper.py:TYPE_CHECKINGimport 追加(F821Run/Project解消・循環import回避)+ 重複ローカル import 削除api/archive/server.py:require_auth重複定義(暫定パススルー版 line10)を削除cli/app.py・api/routes/openrouter_key.py: B904 7件にraise ... from追加(例外チェーン明示)ui/settings_tab.py: 未使用 Gradio 変数を式文に変更(F841)analyzer/_config.py・utils/tree_sitter/_config.py: tree_sitter 可用性検出 import に# noqa: F401(意図的 unused)
Fixed
webapp/auth.py:logger未定義による OAuth callback 失敗時のNameError二重クラッシュを修正(logging.getLogger(__name__)追加)webapp/views_projects.py:_render_run_status_badge再エクスポートを# noqa: F401で保護(safe-fix の過剰削除でviews_dashboard/views_logsの import が壊れたのを修復)
Removed(tests/)
- TextLocalization/StateMachine テスト削除:
fbf09c7bで requirement_agent Gradio UI ごと削除されたがテストが追従せず skip 残存していた dead テスト(test_requirement_agent_comprehensive.py・test_requirement_debugger_comprehensive.py)を除去
Verified
ruff check src/: All checks passed!(53→0)ruff check tests/: 235→50件(safe-fix 181件 + dead テスト削除 約30件解消)※残り50件(F841/F401/E731/B017等 + test_server_execute.py の dead ファイル)は別タスク- pytest 4905 passed(7件 failed は全て pre-existing・本変更と無関係: Redis未設定/Celery/tree_sitter_checker 未定義属性)
[2026-08-06] - Celery タスク冪等性・再実行保護 Plan1(C3・Redis SETNX分散ロック)
Added
src/nexuscore/webapp/task_lock.py: Redis SETNX 分散ロック utility(acquire/release/heartbeat/producer_lock・Lua script で原子 CHECK-AND-DEL・所有者誤解放防止)_acquire_execution_lockヘルパ(celery_app.py): SUCCESS skip + ロック取得をテスト可能単位に切り出し_celery_idempotency_configヘルパ: 環境変数から Celery conf 構成(acks_late/reject_on_worker_lost/track_started/visibility_timeout)NotificationLogモデル: UNIQUE(run_id, event_type) で Slack 重複送信防止- マイグレーション
9d8346475f27_add_notification_logs(915be6eb487e の chain・autogenerate・drift検証済) docker-compose.saas.ymlwebapp/celery-worker に Celery 冪等性設定環境変数追加(VISIBILITY_TIMEOUT=7200 は acks_late 長時間タスクに必須)
Changed
celery_app.pyタスク装飾子:TASK_OPTIONS定数化・acks_late/reject_on_worker_lost/bind=True/autoretry_for(一時的例外5種)/retry_backoff(最大120s)/jitter/max_retries=5celery_app.py_run_orchestrator_task_internal: 本体を try/finally で囲み Redis ロック取得/SUCCESS skip/例外時確実解放(閾値ヒューリスティック撤回)celery_app.py_finalize_run: Slack 通知を NotificationLog UNIQUE で冪等化views_projects._dispatch_celery_run/api/routes/_projects_runs.py: producer_lock(10s) + 決定論的 task_id(orchestrator-run-{run_db_id}) で重複 enqueue 拒否(失敗時 409)
Security
- Qiita六か条監査 CRITICAL #3 対策(Plan1): worker落ち/再配送/重複 enqueue による2重実行を確実に防止
- multi-llm-review(Gemini+MiniMax両LLM CRITICAL一致)で当初「閾値1hヒューリスティック」を撤回し Redis SETNX 分散ロック+決定論的 task_id+producer 二重防御を採用
- 実例:
obsidian-ssot/00_SYSTEM/参考資料/LLMサボりバイアス実例/2026-08-05_閾値ヒューリスティック設計サボり-C3Celery冪等性.md
Verified
- 22テスト全pass(task_lock 6 / celery_task_options 5 / execution_lock_guard 4 / producer_guard 2 / notification_log 2 / finalize_idempotency 1 / celery_idempotency_config 2)
- drift検証: notification_logs マイグレーション後 “No changes”(models.py完全一致)
Constraints / 残課題(Plan2)
- (4) Orchestrator内部冪等性は別Plan: step完了マーカー+LLM結果キャッシュ(JobStateMachine への step API 新設を含む大規模)・Plan1完了後に着手
- PostgreSQL/Redis本番検証はdocker導入後(C1/C2と同方針)・現段階は fakeredis+SQLite 検証
autoretry_for完全正規化層(RetryableError 共通基底)は Plan2 で完全化
[2026-08-05] - DBマイグレーション初期スキーマ管理(C2・autogenerate + migrateサービス分離)
Added
migrations/versions/915be6eb487e_initial_schema_6_tables.py: 初期スキーママイグレーション新設(users/projects/runs/patch_records/execution_logs/api_keys の6テーブル・全index・FK・openrouter_key_enc含む)。Flask-Migrate autogenerate でmodels.pyから機械生成(手書きによる型・命名ズレ防止)docker-compose.saas.yml:migrateone-shot サービス追加(command: ["flask","db","upgrade"]・restart: "no"・db healthy 待ち)。webapp/celery-worker はdepends_on.migrate.condition: service_completed_successfullyでマイグレーション完了後に起動Dockerfile.webapp:FLASK_APP/PYTHONPATHをENVに明示(standalone・flask dbCLI 実行時の app context 不足防止)
Changed
docker-compose.saas.yml: webapp/celery-worker のdepends_onをリスト形式から dict 形式へ昇格(db: service_healthyでDB受付待ち・起動競合回避)
Removed
migrations/versions/a1b2c3d4e5f6_add_openrouter_key_enc.py: 削除(clean start)。本番運用なし・既存ローカルDBは破棄前提のため、履歴 chain 化より単一初期マイグレーション(openrouter_key_enc内包)の方が誠実。既存ローカルDB運用者はflask db stamp headまたは DB 再作成で追従
Security
- Qiita六か条監査 CRITICAL #2 対策(初期スキーママイグレーション不在 → autogenerate で生成・新規本番の
db.create_all()暗黙依存を解消) - multi-llm-review(Gemini+MiniMax・両LLM CRITICAL一致)で方針転換: 当初「手書きマイグレーション」を撤回し「autogenerate + clean start + migrateサービス分離」を採用(手書きの index/FK 命名ズレ・将来 drift・ENTRYPOINT 起動ループ・SQLite単独検証の不十分さを封じる)
Verified
- SQLite 一時DB で
flask db upgrade→ 6テーブル+openrouter_key_enc作成を確認 - drift 検証: upgrade 済DBに再 autogenerate → “No changes in schema detected”(
models.pyと完全一致) - 可逆性:
downgrade base→ 全テーブル削除 →upgrade head→ 再作成の往復成功・FK 制約(5テーブル6本)正常
Constraints / 将来課題
- PostgreSQL(本番想定)での動作検証は docker 導入後に実施(C1と同方針・現段階は SQLite 検証のみ・方言依存コードは使用せず)
- マイグレーション権限分離(アプリ DML / マイグレ DDL の分離)は将来課題・
MIGRATION_DATABASE_URI導入を検討 - ENTRYPOINT でのリトライ・advisory lock は Init Container(K8s)採用時に再検討
[2026-08-05] - SaaS本番DB バックアップ戦略整備(C1・sidecar + 日次pg_dump)
Added
docker-compose.saas.yml:db-backupsidecar サービス追加(postgres:15-alpine・scripts/backup-db.shを entrypoint・24hループで日次pg_dump + gzip・BACKUP_RETENTION_DAYS=7 で自動削除)dbサービスに healthcheck(pg_isready)追加・db-backupはcondition: service_healthyで起動(db 起動前のバックアップ失敗防止)backup_dataボリューム新設(db-backup が書込・db に/backups:roで共有・リストア用)scripts/backup-db.sh新設(ash 互換・pg_dump を一時ファイル出力→gzip でパイプ失敗を捕捉・リテンション削除)docs/setup/saas_db_backup_restore.md新設(リストア手順・PITR 未対応/外部転送未対応の制限明記)
Security
- Qiita六か条監査 CRITICAL #1 対策(本番DBバックアップ戦略不在 → 日次フルバックアップで対応・PITR/外部転送は別タスク)
- B案(C1→C2→C3→C5→C6)の先頭タスク・sentaku L3 + nemotron レビューで「本番運用可能主張には実証根拠先決」と確定した進め方
[2026-08-05] - CI secret-scan 追加・README静的解析宣言の正直化(C6段階的+E)
Security
.github/workflows/ci.yml: gitleaks-action@v2 による secret-scan job を追加(git 履歴全体を走査・continue-on-error: trueで警告モード導入・順次厳密化)・Bandit に加えシークレット混入を検知
Changed
README.md: 「ruff + mypyの静的解析も通過」を正直化。実態は「ruff は変更ファイル単位で検証(verify-post-tool-use hook)・全走査では288件の既存違反が残存(src/53+tests/235)・mypy はCI未実行」だったため、「Bandit(CI必須)+ ruff(変更ファイル単位)+ gitleaks(シークレット走査)で担保・ruff 全走査違反と mypy は段階的CI導入予定」に修正- C6(Qiita六か条観点監査 CRITICAL #6)の前提崩壊を記録: README宣言(ruff+mypy通過)は変更ファイル個別のみ・全走査では288件の既存違反で宣言と実態が乖離 → C6「CI保護の完全実施」は前提として既存違反の一括解消(別タスク L 粒度)が必要と判明。本次は gitleaks 警告モード追加のみ実施(small win)
[2026-08-05] - /api/v1/execute project_path バリデーション追加(C4・パスインジェクション型IDOR対策)
Security
api/routes/execute.py:validate_project_path関数を新設し、/api/v1/executeのproject_pathを検証(Qiita六か条観点監査 CRITICAL #4 対応)os.path.realpathでシンボリックリンクを解決(/tmp/evil -> /etcのような回避を防止)- 機密システムパス(
/etc,/root,/proc,/sys,/dev,/boot,/usr,/sbin,/bin,/lib,/lib64,/var/log)配下を拒否 - 機密ディレクトリ名(
.ssh,.gnupg,.aws)をパス要素に含む場合を拒否 - 違反時は
ValueError→ エンドポイントでHTTPException(400)に変換 - 従来は
os.path.abspathのみで、認証済ユーザーが任意のサーバーパス(/etc,~/.ssh, 他人プロジェクト)でオーケストレータ(ファイル書込・subprocess実行)を起動可能だった - 完全なユーザー別プロジェクト隔離(project_id 経由)は別タスク(M粒度)として残置
- テスト追加:
tests/api/test_execute_path_validation.py(機密システムパス拒否12件・機密dir拒否6件・正当パス許可5件・シンボリックリンク攻撃回避2件)
Changed
.gitignore:.env→.env*に強化(.env.bak.*/.env.local等の派生ファイルを包括無意・誤git addによる公開事故防止・!.env.template例外は維持)
Fixed
api/routes/execute.py: 既存 import ブロック順序(I001)をruff --fixで整理(本変更の副作用で表面化)
[2026-08-04] - pytestサブプロセス呼び出しの python ハードコード修正(sys.executable化)
Fixed
- pytest を起動するサブプロセス呼び出し3箇所でインタープリタを PATH の
"python"リテラルで固定していたのをsys.executableに変更(venv 不整合防止・実行中プロセスと同一インタープリタを使用)core/phase_runner_mixin.py:461,542(run_in_sandbox経由の pytest 実行・初回テスト&デバッグループ再テスト)core/quality_regen_loop.py:43(measure_coverageのカバレッジ計測)- 従来は PATH の
pythonに依存し、venv 外のシステム python が呼ばれてModuleNotFoundError等の不整合が起きうる状態だった。デモ作成時は symlink で応急対応していたが本質修正(handoff 2026-08-04_1117_e3d4 の未解決事項)
- テスト追加:
tests/core/test_quality_regen_loop.py::test_uses_sys_executable_as_interpreter(cmd[0]==sys.executable を機械検証)+ 同ファイルの既存 lint(I001 import sort / F401 unusedQualityRegenResult)を整理
[2026-08-04] - 見せる用デモ素材追加(CLI録画GIF・スクショPNG)
Added
- デモ用GIF:
docs/demo/gifs/cli_pipeline_demo.gif(CLIパイプライン12エージェント連鎖の様子・asciinema録画→agg変換・--font-size 20・Gemini+4_5v MCP の2LLM相互検証済) - デモ用スクショPNG 3枚:
docs/screenshots/cli_pipeline_{phase0_start,mid,phase4}.png(CLI実行各フェーズの静止画)
[2026-08-02] - 低優先度リファクタリング(コード品質スイープ低優先度残・agents/analyzer)
Changed
- agents:
policy_agent.pyの▼▼▼/▲▲▲装飾コメント削除、council_cli.py/council_webui.pyの未使用import(pathlib.Path)除去、_fallbacks.py/council_cli.py/council_webui.pyにモジュールdocstring追加 - analyzer:
context_analyzer.py/context_agent.pyのWindows固有パスコメント(📁 C:\Users\USER\...)削除、graph_builder.pyのImportError文にpip install networkx案内追加、_engine.pyAnalysisResult のtimestamp/data型ヒント補完 - analyzer:
context_analyzer.pyの B013 冗長タプルexcept (OSError,)→except OSError修正(7件・ruff自動修正) - llm:
llm_router.pyの未使用import(REQUEST_TIMEOUT)除去(#15)、_model_detection.py/_router_utils.py/llm_router.py/provider_factory.pyの import 順序整形(I001・4件) - services:
git_operations.pyのbase_dirに型アノテーション(str | None)付与(#13) - ui:
settings_tab.pyの未使用import除去(F401・#16関連ファイル) - utils:
tree_sitter_checker.pyの未使用import除去(F401・4件)/import順序整形(I001)、ついでに verbose 時の_loggingalias 不整合による NameError 潜在バグを修正(import sortで表面化)
Fixed
- 調査(2026-05-26)の鵜呑み回避: 実コード確認で既に解消済み(#16 マジック文字列定数化/#18 インスタンス属性化)や誤検知(#25 例外設計/#22 Sentinel値)を判定し、対象外を記録
第2セッション追加対応(58dc完了後・11コミット・新規failureなし)
58dcが「スキップ(妥当)」とした5エリア(npe/config/api/core/webapp)を含む残り項目を、3 Explore agent での現存確認を経て追加改善。項目レベル重複なし・ベースライン(2 failed/4861 passed)完全一致。
- npe:
_read_today_totalに行解析ヘルパ_parse_ledger_cost抽出(#11) - config: フォールバック project version をモジュール定数化(#9)
- api:
MAX_API_KEYS_PER_USERを env(NEXUS_MAX_API_KEYS_PER_USER)化(#12) - utils:
cleanerの「Return None」誤コメント削除(#13)/test_strategyos.getcwd のOSErrorフォールバック(#18)/zip_output除外dir定数化+output_dir存在保証(#19) - ui:
ai_revision_tabのコードブロック除去をcode_prompt_tab._strip_code_blockで共通化(#19) - webapp: CORS origins を env(NEXUS_CORS_ORIGINS)化(#24)/
paginate_query戻り値型を具体化(#31) - services: self_healing session_id を env(NEXUS_SELF_HEALING_SESSION_ID)化(#15・format全面整形混入をreset→surgical再適用)
- llm:
BudgetManager/log_transactionにdocstring追加(#18) - core:
NexusOSKernel.get_service戻り値型-> Any(注:NexusOSKernel は code_interpreter 不在で import 不可・死にコード候補)(#15) - analyzer:
context_analyzerプレビュー読込 10000 →_PREVIEW_READ_BYTES定数化(#19) - agents:
council_cli.run_cli_menuにdocstring(#21・他項目は解消済み/誤検知/設計判断でスキップ)
[2026-07-30] - LLM stub応答の silent failure 解消(real無効時に明示的WARN)
Fixed
BaseLLM._stub_response(real呼出無効時・APIキー無し等)が黙ってダミー応答を返し「本物のLLMが動いたか」が実行時に判別不能だった問題を解消。stub応答時に WARN ログ(モデル名・原因候補含む)を出し、stub動作を即判別可能にsrc/nexuscore/llm/providers/base.py:_stub_responseにlogger.warning追加tests/llm/test_stub_response_warn.py(新規3テスト): WARN 出力・レベル検証・fallback(今回対象外)の非変更を検証- ついでに:
base.pyの pre-existing な unused import(typing.Any)を削除(触ったファイルの lint クリーン化) - 検証: tests/llm 641 passed / 変更ファイル ruff+mypy 緑
- 範囲: real無効時(
_stub_response)のみ。real失敗時(_stub_fallback_response)は既存log_error(ERROR)あり据え置き
[2026-07-30] - NEXUS_TASK_MODEL_* デッドキー是正(env でモデル振り分け切替可能に)
Added
NEXUS_TASK_MODEL_CODING/REVIEW/GENERALの3 env キーをコード参照し、各カテゴリの primary モデルを env 1行書き換えで切替可能に(2026-07-23監査④デッドキー是正)。値は profile ID(glm_default/gemini_secondary/minimax_default等)src/nexuscore/llm/task_model_map.py:_TASK_CATEGORY(task→coding/review/general 分類・2026-07-23 3LLM集約構成に準拠)・_CATEGORY_ENV・_resolve_primary()を追加。build_task_model_map_dict()の primary を env で上書き。alias(testing等)は target のカテゴリを継承tests/llm/test_task_model_env_override.py(新規7テスト): env 上書き(CODING/REVIEW/GENERAL)・未設定時の既定維持・alias カテゴリ継承・未知値フォールバック・secondary/fallback 非上書きを検証
Changed
- env 値が未知の profile ID(model name 形式や typo 等)の場合は 警告1回+既定フォールバック(移行安全性)。
fail-fastでなく既存.envの古い値(gpt-5等)でもクラッシュせず稼働。警告は env キーごと1回に重複抑制(_WARNED_BAD_ENV) - 検証: tests/llm 638 passed / 変更ファイル ruff+mypy 緑 / 実
.env環境で起動時ビルド確認(3カテゴリ各1回 warn・既定フォールバック・33エントリ build OK)
[2026-07-28] - MiniMaxモデル名表記の不統一是正(MiniMax-M3 PascalCase統一)
Fixed
- MiniMaxモデル名の表記揺れ(
minimax-m3小文字 /MiniMax-M3PascalCase)をMiniMax-M3に統一。実API(.envのMINIMAX_MODEL=MiniMax-M3)と整合しない小文字表記が残存し、_call_minimaxがenv未設定時に小文字を送ってAPIで弾かれるリスクがあった src/nexuscore/llm/llm_profiles.py:minimax_default/minimax_analyticalのmodelをminimax-m3→MiniMax-M3に是正src/nexuscore/utils/test_generator.py:_call_minimaxのデフォルト(env未設定時フォールバック)をMiniMax-M2.7(旧モデル)→MiniMax-M3に更新tests/llm/test_llm_profiles_comprehensive.py・tests/utils/test_test_generator_comprehensive.py: 上記に追従。test_call_minimax_sends_correct_payloadはMINIMAX_MODELenv を明示セットして.env流入を防ぐ堅牢化(従来はenv未隔离でフルスイート時のみ1件FAIL)- 検証: LLM系 681 passed / フルスイート 4905 passed・0 failed(従来 4904 passed, 1 failed から失敗ゼロ化)
[2026-07-26] - 未完成エントリポイントの棚卸し(main_cli.py以外)
Removed
src/main_ui.pyを削除 — 2025-01「4.5 UI統合」でunified_gradio_ui.pyに統合された後の抜け殻。フォールバック先のapp_ui.py/revision_loop.py/streamlit_migrated_tab.py/interactive_generator.py(src/gradio_app/・src/modules/配下)はdb0424d8(no imports found確認済み・archive/ごと削除)で既に消滅済みで、参照先自体が存在しないため到達不能。現行の起動経路はunified_gradio_ui.py直接起動(AGENTS.md/CLAUDE.md記載)で完全代替済みsrc/dev_tools/test_manager.pyを削除 —code_generator/diff_viewer/tester/whisper_handlerをimportするが、これらのモジュールはリポジトリ全体のどこにも存在せず、import時点で確実にImportError→sys.exit(1)。他のどこからも参照されておらず、稼働実績なしtests/ui/test_main_ui.py・tests/ui/test_main_ui_unit.pyを削除 —main_ui.py専用のカバレッジ稼ぎ用テスト(tkinterベースの存在しない関数をhasattrチェックするのみ・実体テストなし)。対象モジュール削除に伴い道連れ削除- 経緯:
app.py:73(nexusCLI)の戻り値契約ズレバグ修正(2026-07-21・PR #106)を機に、「他のエントリポイントにも同種バグが眠っている可能性」を全経路棚卸し。nexusCLIの他コマンド・unified_gradio_ui.py(Dynamic Runタブ含む)・bootstrap_apikey.pyは契約ズレなしと確認、上記2ファイルのみ「デッド経路」として検出 - 詳細:
01_DECISIONS/NexusCore/2026-07-26_未完成エントリポイントの棚卸し.md(※記録予定)
[2026-07-26] - CoderAgent説明文出力の根源改善(案X′・コードブロック必須化)
Changed
CoderAgent説明文出力の根源改善(前回 2026-07-23 fail-safe化 の上流・問題③decision 案C実装):- ①
implement_codeプロンプトに「python 〜マークダウンコードブロックで囲んで出力せよ」を明示(LLM側防波堤) - ②
_extract_code_from_response: コードブロック未検出時の「レスポンス全文フォールバック」(説明文をコード扱いする経路)を廃止 → 空文字返却に変更 - ③
_validate_code: 冒頭に空ガードif not code.strip(): return False, "empty code"を追加(ast.parse("")が成功する仕様の穴対策・_validate_code層=言語非依存に配置しSRP適合)。結果: コードブロック無し→空→AST不合格→RETRY継続でLLMに囲み直しを促し、説明文がコードとして紛れ込む経路を根源から排除
- ①
- 設計経緯: sentaku L3弁証論(Gemini+MiniMax)で案X′(空+空AST不合格化)を採用。Z(空=AST合格のまま)はRETRYが死ぬ・Y(例外)は想定内失敗への例外濫用、をそれぞれ却下
- TDD: RED 6件FAIL確認 → GREEN → 既存10テスト(コードブロック無しモック)を新仕様のコードブロック形式に更新 → agents 982 / core 908 全グリーン
- 詳細:
01_DECISIONS/NexusCore/2026-07-26_CoderAgent説明文根源改善-案X′コードブロック必須化.md(※記録予定)
[2026-07-25] - 学習レイヤー実API検証スクリプト追加・python-patch導入
Added
scripts/verify_learning_e2e_real.py新設(Stage3学習レイヤー実API E2E検証・Mock版単体テストの実LLM版・postmortem/knowledge_curatorのみ実LLM化・knowledge_baseはMock化でDB非汚染・5回実行で学習ルート完全マッピング)python-patch(patch-1.16) を.venvに導入(KnowledgeCuratorAgent のサンドボックスパッチ適用に必要・requirements.txt/requirements.lock.txt反映は別途)
Changed
- PatchApplier
allow_deletions=False(curator経由は固定)が学習ルートのcurator検証障壁となることを実API検証で確認(検証スクリプトではモンキーパッチで動作確認・本運用開始時は学習ルートとcommit gateの設計見直しが要) - 詳細: 01_DECISIONS/NexusCore/2026-07-25_学習レイヤー実API検証-3障壁とGLM品質限界実証
[2026-07-24] - _INDEX案C再構成(SSOT体系化 P3-C Phase1)
Changed
docs/superpowers/01_DECISIONS/NexusCore/_INDEX.mdを案C構成に再構成(142件→7テーマ分類: テスト26 / LLM11 / Debugger12 / リファクタ49[設計9/大改修12/調査17/個別13] / CI16 / Docs18 / 横断運用実証8)。代表リンク+1行説明+📅時系列dataview形式。ai-music/reserve-optimizer と一貫- 詳細: 01_DECISIONS/claude-code/2026-07-24_P3-CPhase1-NexusCore_INDEX案C再構成完走-7テーマ+リファクタ4サブセクション.md
[2026-07-22] - NexusCore実API動作確認(GLM主軸・ローカル設定調整)
Changed
- 実API動作用のLLM設定調整(ローカル
.envのみ・非commit): NexusCore CLIの実API呼出が全てstub-fallbackに落ちていた真因を3点で解消。①LLM SDK(openai/anthropic/google-generativeai/zhipuai)をvenvへ導入(requirements.txt最小→lock未適用が原因)②FORCE_CHEAP_FOR_TASKS+CHEAP_LLM_MODEL=glm:glm-5.1で主要タスクをGLM寄せ(OpenAI429/Gemini無効モデル名404を回避)③NEXUS_DEFAULT_MAX_OUT_TOKENS/NEXUS_LLM_MAX_OUTPUT_TOKENSを1024→16384(glm-5.1推論モデルが推論だけで1024を使い切り出力0になる設計不整合)。結果: GLM(glm-5.1)実APIで要件→計画→実装パイプライン完走・フィボナチ関数3ファイル生成成功。詳細:01_DECISIONS/NexusCore/2026-07-22_NexusCore実API動作確認-3壁解消.md
[Unreleased]
Added
- Stage 3 学習レイヤー実配線(
src/nexuscore/core/phase_runner_mixin.py): ①テスト失敗枯渇時にpostmortem_agent.analyze_failure_and_suggest_fkb_entry()→knowledge_curator_agent.validate_fkb_suggestion()を実行し、サンドボックスで実際にテストが通ることを検証できた解のみ中央FKB(database.knowledge_base.add_knowledge())へ永続化(汚染防止・spec §5)。分析結果は検証の成敗に関わらずcontext.postmortem_reportへ格納し、実装済みだが未発火だった_maybe_run_constitutional_review()を初めて起動 ②guardian APPROVE後にpolicy_agent.audit()の結果をallow_commitとしてguardian_agent.review_and_commit()に接続し、ポリシー違反時はコミットをブロック ③debugger⇔中央FKBの接続(_find_solution_from_kb)は既存実装のみで成立することを回帰テストで担保。spec:docs/superpowers/specs/2026-07-17-twelve-agent-pipeline-design.md§5。詳細:01_DECISIONS/NexusCore/2026-07-21_Stage3学習レイヤー実装.md - コード生成系 Agent の層1(AST構文検査)共通ユーティリティ
src/nexuscore/utils/syntax_validator.py新設(validate_python_syntax(code) -> tuple[bool,str]・phase_runner が使用・CoderAgent は6d3fセッション完了後に移行) - 自己修復デバッグループの履歴
OrchestratorContext.debug_history・早期脱出閾値AST_FAIL_LIMIT=2(env:NEXUS_AST_FAIL_LIMIT)・_clean_pytest_cache(CI flaky 回避)・_format_debug_history(NEEDS_HUMAN_REVIEW 時の人間可読要約)を追加
Fixed
- DebuggerAgent 経由の LLM説明文による実装ファイル破損を根本防止(
src/nexuscore/core/phase_runner_mixin.py::run_testing_phaseデバッグループ)。A検証(dynamic完走・2026-07-24)で、DebuggerAgent が生成した fixed_code を適用前検査なしで書き込み→pytest失敗でも復元せず次ループ→破損ファイル(primes.py等)が残り悪化ループになる問題を解消。①層1 AST構文検査で説明文を適用前に弾く②層3 pytest実行検証で意味の正しさを担保③try-finally で例外時も含めループ脱出後に original_source へ復元(破損残存防止・悪化ループ根絶)④AST NG 連続AST_FAIL_LIMIT回で早期脱出(LLMが説明文しか返さない故障検知)⑤各試行をdebug_historyに記録し NEEDS_HUMAN_REVIEW 時に review_report へ添付。ユーザー指摘「AST検査は第一防線・根本対策でない」に対応(実行検証で意味の正しさを担保)。spec:docs/superpowers/specs/2026-07-24-nexuscore-debugger-patch破損根本防止-design.md・2巡 multi-llm-review(Gemini+MiniMax)経由。テスト8ケース追加(破損防止/早期脱出/連続判定/空fixed_code/例外安全/最終ロールバック/履歴蓄積)
Fixed
src/nexuscore/cli/app.py:73—nexus runコマンドがorchestrator.run_full_project()の戻り値に.get("status")を呼んでいたが、同メソッドはOrchestratorContext | None(dataclass、.get()無し)を返すため、成功時・停止時いずれもAttributeErrorで必ず落ちていた(nexusはpyproject.toml:9 [project.scripts]で公開される現役エントリポイント。CLIテスト未整備で露見せず)。result is None→interrupted、それ以外→completed (N phases)(phase_log由来)に導出するよう修正。回帰防止にtests/cli/test_app.pyへ context 返却/None 返却の2ケースを TDD で追加(監査「複数の未完成エントリポイント同居」パターンの一例)- CI修復:
NexusCore CI/CDワークフロー赤の3問題を解消。①test matrix から Python 3.9 除外(semgrep==1.166.0/pip-audit==2.10.1/bandit>=1.9.0が Python 3.10+ 必須のため。3.9が落ちるとmatrix全体がキャンセル連鎖で全バージョン赤になる構造的問題でもあった)②Bandit スキャンがsrc/sandbox_logs/(72ファイルの修復ログ・AST parse失敗する自然言語テキストを.py拡張で持つ)を除外するようpyproject.toml [tool.bandit].exclude_dirs追加 —Check for critical vulnerabilitiesステップは-lll(High only) でB104 Mediumは元から通過するため、High:0で緑化 ③actions/upload-artifact@v3→@v4(2箇所・v3はGitHubで削除済・Node20 deprecated警告解消)④Codecov 連携ステップ削除(CODECOV_TOKEN未設定でfail_ci_if_error: trueのため赤確実。CI緑化優先・後日Codecov.io登録&token設定で再有効化)⑤pytest を-n auto --dist=loadfileから直列実行に変更(5000件規模でグローバル状態リーク由来のフレーク確認。直列化でフレーク消失を確認。CI時間は+5-10分)⑥test_generator 周辺の3テスト(フルテスト時のみフレークするtest_test_generator_creates_runnable_pytest_file/test_init_without_genai_library_falls_back_to_stub/test_generate_unit_tests_uses_default_config)に@pytest.mark.xfail付与。test_generator 機能改善時に解消予定(別Issue)⑦ci.yml の bandit コマンドに--exclude src/sandbox_logs/を明示(4箇所・pyproject.toml の exclude_dirs はCIで読まれず sandbox_logs がスキャンされていた問題を解消)⑧requirements-dev.txtにpytest-timeout追加(pytest.ini の--timeout=120がCI環境で unrecognized arguments エラーになる問題を解消)⑨ci.yml の display用bandit -r src/ -llに|| true追加(実コードのLow+ severity偽陽性でexit 1になりCI赤になる設計ミスを解消。厳密判定はCheck for critical vulnerabilitiesステップが-lllで担当)⑩ci.yml matrix を["3.12"]のみに(pyproject.tomlrequires-python >=3.12と整合・datetime.UTC(3.11+)のコア10箇所使用のため3.10以前は不可)⑪Bandit Medium+ 5件の実体解消(セキュリティレビュー指摘対応・|| true後退を撤廃): B104/B608 はarchive/配下(非現用)→ bandit--excludeに archive 2ディレクトリ追加で自然消滅・残る B108(/tmp偽陽性3件: run_lock/sandbox_config/dynamic_run_tab placeholder)は実コードに# nosec B108明示・critical check を-lll(High only)→-ll(Medium+)に厳密化(ローカル実走で Medium:0 High:0 exit:0 確認) - v3レビュー P0「api/dependencies/orchestrator.py:62-63 空文字列認証フォールバック」— doubt-driven で検証した結果、
api_keyは GuardianAgent 内で使用されないデッド変数(実際のLLM認証はLLMRouterが env 経由で担う)と判明。真の論点は「3経路の cred 出所バラバリ + デッドコード」であり、cred 出所をGuardianAgent.__init__内 env 読込の1箇所に集約して解消(A’案)。placeholder 廃止・重複排除も達成 - CI修復続き(Run Tests 3.12 gradio不整合解消)⑫:
requirements.txtのgradio>=4.16.0,<5.0.0→gradio>=4.16.0,<7.0.0に制約緩和。gradio 4.x は古い huggingface_hub API(HfFolder)に依存し、CI が最新 huggingface_hub(1.x・HfFolder削除)を入れて ImportError になる問題を解消。gradio 6.x(HfFolder不使用)でローカル.venv実証済み。NexusCore は gradio をimport gradio as grの標準使用のみ(4.x固有APIなし)のため6.x互換 - CI修復続き(Run Tests 3.12 TemplateNotFound解消)⑬:
.gitignoreの「# エージェント残骸 webapp/」がsrc/nexuscore/webapp/templates/配下のHTML10個(base.html/components×2/dashboard×2/logs×2/projects×3)を巻き込み除外していた。CI の git clone に含まれずjinja2.exceptions.TemplateNotFound: logs/project_logs.htmlで ci.yml 3連赤(gradio解消⑫で40%まで進むよう初めて顕在化した「過去緑CI履歴ゼロ」の真因)。「エージェント残骸 webapp」は現在実在しない(src=ソース必須/tests=テスト必須/mutants=別管理のみ)のためwebapp/ignore 行を削除し、テンプレート10個を git add。ローカル.venv は元々ファイルがあるので通過(tests/webapp/ 39 passed)・CI固有問題。ci.yml 両job(Run Tests 3.12 in 4m52s / Security Vulnerability Scan)緑化確認(run 29017144120) - CI修復続き(Release Drafter workflow削除)⑭:
.github/workflows/release-drafter.ymlを削除。Release Drafter は「マージされたPR」ベースでリリースノート生成するが、NexusCore は main 直push 運用(PR経由なし)のため変更一覧が空になり機能しない(doubt-drivenで気づき・A案設定追加からB案削除に訂正)。設定ファイル欠落で3s失敗し続けていた赤を解消。今後PR運用(チーム/OSS化)に変える場合は再導入可 - CI修復続き(STIT approval-notification 構文解消・CI完全緑化)⑮: push毎0s赤の真因を actionlint 導入で特定→
if:式のメソッド構文github.event.issue.title.startsWith('...')(GitHub Actions式に非存在)を関数構文startsWith(A,B)に修正(L23/L137)。job レベル schedule 削除(bbeb1c73)は副次・真因はif式(c550008f)。構文解消で on: トリガー通りに動き(push トリガー無し→pushで走らない→赤停止)。2LLMレビュー(Gemini B案/MiniMax E案)は「NexusCore開発停止中」文脈でD案(残す+赤だけ消す)に転換。STIT運用は保留・branch-validation/test-pipelineはpull_requestのみ(将来再開時修正点: codecov v3→v5・github.head_ref env経由)。これで ci.yml緑化+Release Drafter削除+STIT赤停止=CI完全緑化 -
CI修復続き(STIT PR ワークフロー Python 3.11→3.12 統一)⑯:
stit-branch-validation.yml/stit-test-pipeline.ymlがactions/setup-pythonで Python 3.11 をセットアップ後にpip install -e .していたが、pyproject.tomlはrequires-python >=3.12のためERROR: Package 'nexuscore' requires a different Python: 3.11.x not in '>=3.12'で必ずインストール失敗し、全PRでValidate branch name/STIT Process Validationが9s赤(ブランチ名・STIT本体の検証に到達すらしていなかった)。両ワークフローのpython-version: "3.11"を"3.12"に統一(ci.yml⑩と同判断)し、stit-test-pipeline.ymlの run-tests matrix["3.9", "3.10", "3.11", "3.12"]を["3.12"](coverage include も 3.12)に集約(3.12未満は nexuscore を入れられない)。stit-approval-notification.yml(PR では python セットアップ不要のジョブのみ起動・pip install -e .なし)とnexuscore-safe-tests.yml(3.11のまま緑・pip install -e .なし)は赤に無関与のため非変更。併せて、Python 3.12 化でstit-test-pipeline.ymlの run-tests が初めて完走するようになった結果、最終Upload coverageステップ(codecov/codecov-action@v3+fail_ci_if_error: true)がcoverage.xml不在(run-tests は--cov-report=xmlを付与しないため生成されない)で exit 255 → 赤になる潜在不具合が顕在化したため、当該ステップを削除(ci.yml④ と同処置・テスト本体は pass)。 src/nexuscore/core/goal_spec.py:107—has_implementationcriterion のキー不整合修正(2026-07-23 問題②・dynamic完了判定ループの真因)。criterion がctx.implementation.get("code")のみ見ていたが、通常パイプライン(phase_runner_mixin.py:350)は{"files": generated}を設定するため.get("code")=None→永遠 unsatisfied→max_actions 枯渇(fast_lane({“code”:…})だけ動いて見えた)。criterion を_non_empty(get("code")) or _non_empty(get("files"))に修正(両経路対応・空 dict は _non_empty=bool で False=未達維持)。2LLMレビュー(Gemini+MiniMax)で真因肯定・MiniMax の空dict懸念は _non_empty=bool で解消・回帰テストで保険。TDD: RED(files形式で未達)→GREEN→空dict未達テスト追加。goal_spec/dynamic系 60件 全通過src/nexuscore/agents/coder_agent.py:73—implement_codeの RETRY枯渇時挙動を fail-open → fail-safe に修正(2026-07-23 Smoke Test 破損事故の真因)。AST検査がRETRY_LIMIT(2回) 連続失敗した場合、従来は最後のAST不正コードをそのまま返していた(fail-open)。LLM(GLM)がコードでなく説明文を返した場合、それが説明文のまま_generate_one_fileの空チェック(if not code)を潜り抜け、__init__.pyに日本語説明文が保存されて破損(SyntaxError: invalid character '、')。RETRY枯渇時は空文字を返すようにし、phase_runner_mixin.py:383の空チェックが保存を弾く構造に。バックログ旧案「python-patch導入」は systematic-debugging で無関係と確定(python-patch/patch_applier/self_healing はPR系修復の別系統・Phase4生成パイプラインと無関係・decision の因果誤認)。副修正(phase_runner保存前AST検査)は主修正+既存空チェックで不要と判断。TDD: RED(説明文返却で失敗確認)→GREEN(73行修正)→旧仕様固定テストtest_implement_code_max_retries_exceededを新仕様化 + 新規test_implement_code_returns_empty_when_all_retries_fail追加。coder_agent系 39件 + phase_runner/orchestrator系 75件 全通過
Changed
tools/brownfield_orchestrator.py— God file 分割(v3レビュー P1): 485行単一ファイル →tools/brownfield/パッケージ5モジュール(utils/core/ui/__main__/__init__)+ 18行 thin shim(後方互換)。python tools/brownfield_orchestrator.py --uiは変更なしで動作。baseline 前後比較テスト(normalize()でタイムスタンプ/tmp_path 正規化)で振る舞い保存を証明。依存方向utils ← core ← ui ← __main__(循環なし)・__init__.pyは lazy__getattr__(gradio 遅延読込)。セキュリティ指摘(B602 subprocess shell / B104 0.0.0.0 bind / path traversal 5件)は旧コード由来のため別Issue化(C案 scope-out)。詳細:docs/superpowers/specs/2026-07-01-brownfield-orchestrator-split-design.md・実装計画:docs/superpowers/plans/2026-07-01-brownfield-orchestrator-split.mdsrc/nexuscore/agents/guardian_agent.py—GuardianAgent.__init__のmodelをGUARDIAN_MODEL環境変数参照に変更(cred 出所の集約)。api_key引数は後方互換のため残置。v3レビュー P0 対応src/nexuscore/api/dependencies/orchestrator.py—get_orchestrator()をassemble_agent_team()ベースに統合(API 経路が最後の孤島)。_load_guardian_credentials()廃止・3経路(CLI/webapp/UI)と同一パスに統一src/nexuscore/core/agent_factory.py—assemble_agent_team()にlanguage/knowledge_base_path引数追加(既存呼出は default で非影響)main_cli.py—_load_guardian_credentials()(placeholder 含む)廃止。GuardianAgent()引数なしで cred を GuardianAgent 内 env 読込に統一src/nexuscore/analyzer/context_analyzer.py— ハードコードフォールバック5箇所(requirements 解析/依存関係/標準ライブラリ/Pythonバージョン)を環境変数NEXUSCORE_CONTEXT_FALLBACK_*で上書き可能に設定化。未設定時は従来のデフォルト値を維持(後方互換)。v3レビュー P1 対応src/nexuscore/utils/cleaner.py— モジュールdocstring・各関数の型ヒント(get_error_header(traceback_str: str) -> str/clean_error_msg(error_str: str = "") -> str)・docstring追加。振る舞い変更なし(67テスト全PASSで回帰確認)
Security (Phase 2 脆弱性監査 — api/ 深掘り)
src/nexuscore/api/routes/execute.py:191-198—/executeでpayload.project_pathを認証済みなら誰でも渡せて、Orchestrator が任意パスを操作可能 (H-1 HIGH)src/nexuscore/api/routes/execute.py:191—payload.requirementにサイズ制限なし → 巨大なプロンプトで Token DoS (OWASP LLM04)、コンテンツ検証なしで プロンプトインジェクション → PolicyAgent バイパスの可能性 (H-2 HIGH)- 副次:
/run-recordsページネーションなし (MEDIUM)、SessionMiddlewaredefault secret_key (LOW、fastapi_app.py:124) - 修正方針: C 案 (project_id 化) +
requirement: Field(..., max_length=2000)、ユーザー合意待ち - 詳細:
01_DECISIONS/nexuscore/2026-06-17_Phase2-api-任意コード実行とプロンプトインジェクション.md
Added (Security audit Phase 0 — ベースライン取得・計画策定)
- セキュリティ監査ツール4種を
requirements-dev.txtに pin:bandit==1.9.4/semgrep==1.166.0/pip-audit==2.10.1/detect-secrets==1.5.0 - ベースライン検出サマリ: bandit 10526件 (HIGH 8 / MEDIUM 150 / LOW 10368)、semgrep 12 WARNING、pip-audit 53件 (17 pkg、52 HAS_FIX / 1 NO_FIX=gradio)、detect-secrets 6件 (全件
.claude/settings.local.json由来、gitignore 対象) - 脆弱性発見計画 v0.1 を
docs/security/vulnerability_discovery_plan.mdに追加 — Phase 1 でフィルタ最適化→真陽性抽出→修正のロードマップを明文化 - ベースライン JSON 出力:
docs/security/baseline/*.jsonおよびdocs/security/baseline/phase0_baseline_report.md - High 候補 6件 (Phase 1 で均等に精査予定):
tools/brownfield_orchestrator.py:111shell=True (B602) /council_webui.py:124SSTI 疑い /server.py:2900.0.0.0 バインド (B104) /auth.py:47Host ヘッダ依存 /archive/views_api_test.py:65B608 f-string SQL /tools/配下 7箇所 SHA1 (B324) - 偽陽性として除外予定: bandit B101 assert × 9986 (テストでは許容)、B404/B603 subprocess × 90 (CLI ツールで必須、検証済なら安全)、semgrep
python-logger-credential-disclosure(誤検知: ログは set/unset のみ)
Added (CR-NEXUS-054 Phase C — CLI/UI統合・完結)
main_cli.py:--dynamic/--dynamic-llm-routing/--max-actions/--skip-actionsフラグ追加。run_dynamic_mode()でDecision Traceをログ出力、ゴール未達はexit code 1ui/dynamic_run_tab.py: 統合UIに「Dynamic Run」タブ追加 — 要件・パス・予算・スキップ/LLMルーティング指定で動的実行し、結果とトレースを表示- テスト6件追加(GLM生成→Fable検証)。CR-NEXUS-054 全フェーズ完了(Spec → Completed)
Fixed
core/orchestrator.py:context_agentフィールド欠落を修正 —main_cli.pyとagent_factory.assemble_agent_team()が渡すcontext_agent引数をOrchestratorが受け取れずTypeErrorでCLIフルパイプラインが起動不能だった既存バグ
Added (CR-NEXUS-054 Phase B — LLM支援ルーティング・計測クライテリア)
core/llm_assisted_router.py: LLMAssistedRouter — 軽量ティアLLMが次アクションを提案、無効提案・LLM障害・予算超過は必ずRuleBasedRouterにフォールバック。リトライ判断は決定的ルールのまま。from_llm_router()で既存LLMRouterと統合可能core/measured_criteria.py: coverage_criterion / lint_clean_criterion — カバレッジ%・lint警告の実測ベース成功条件。PhaseCachedCheckでphase_log変化時のみ再計測(pytest多重実行防止)- テスト18件追加(MiniMax生成→Fable検証。GLMタイムアウトのためフォールバック)
Added (CR-NEXUS-054 Phase A — ゴール駆動・動的オーケストレーション)
core/goal_spec.py: GoalSpec / SuccessCriterion / GoalEvaluator / standard_criteria — ゴール(達成条件・予算・スキップ)を宣言的に定義し決定的に採点core/dynamic_router.py: ActionRegistry(既存 run_*_phase を自動登録)+ RuleBasedRouter(未達条件→次アクションをLLMコストゼロで選択)core/dynamic_orchestrator.py: DynamicRunLoop — 既存Orchestrator無改変のコンポジションでゴール達成まで動的実行。失敗は全停止せずアクション単位リトライ、全判断をDecisionTraceに理由付き記録- テスト48件追加(
test_goal_spec.py/test_dynamic_router.py/test_dynamic_orchestrator.py、MiniMax生成→Fable検証) - 仕様書:
docs/spec/CR-NEXUS-054_Dynamic_Goal_Driven_Orchestration.md
Changed (UI分離完了 — Phase 1完遂)
config/policy_interface.py→ui/policy_interface.pyに移設(Gradio UIコードをui/層へ集約、参照8ファイル更新)docs/overview/03_Development_Roadmap.mdv1.3: 実態に合わせて更新(カバレッジ81%・8プロバイダー・Phase 1のUI分離/DebuggerAgent自動PRを完了マーク)
Removed
utils/app.pyをarchive/legacy_flask_gradio_app.pyへ移動(存在しないroutes_ai_repair/gradio_uiをimportする死んだレガシーコード)、関連テスト3本削除- これにより ui/層外のGradio依存ゼロ を達成
Added
- 退避ブランチからカバレッジテスト7ファイル・約200テストを回収(
archive/*タグ監査の成果)tests/agents/test_base_agent_fallback_paths.py(issue-86)tests/api/test_api_keys_coverage.py(issue-90)tests/api/test_fastapi_app_coverage.py(issue-92)tests/api/test_auth_dependency.py(issue-96、モック記述ミス1件修正)tests/agents/test_policy_interface_coverage_boost.py(import先をconfig.policy_interfaceに修正、print検証→loggerモック検証に更新)tests/core/test_retry_policy.py/test_errors.py(feature/fail のミューテーションキルテスト、32→52テスト)
- 回収見送り:
test_api_auth.py(対象のapi/auth.pyはPhase 5で統合済み)、test_requirement_agent_fallback.py(対象のTextLocalizationは8.2.1で削除済み)
Fixed
api/routes/github_webhook.py: PRコメント投稿・Slack通知をasyncio.to_threadでバックグラウンド実行化(Webhookレスポンスのイベントループブロック解消)
Changed
.gitignore: デモGIF生成の中間ファイル(docs/demo/frames/,docs/demo/svgs/)を追跡対象外に- ローカルブランチ掃除: マージ済み9本を削除、未マージ13本は
archive/*タグに退避して削除(Issue #50自動PR・Issue #75 CI並列化はmain取込済みを確認)
Added
ArchitectAgent.design_architecture(specs, plan)新設。coderへの設計方針(design_directive)注入用(Stage 2・spec §4-1)- Phase 5(testing)を全面書き換え: テストファイルをplanのtarget_files(role=test)へ書き出し、
run_in_sandboxでpytest実行、失敗時はDebuggerAgent.debug_and_patchで最大3回(NEXUS_DEBUG_MAX_RETRIES)まで自動修正ループ(Stage 2・spec §4-2) - Phase 6(review)を全面書き換え:
GuardianAgent.reviewでコードレビュー、REJECT時はフィードバックを添えて最大2回(NEXUS_REVIEW_MAX_RETRIES)まで再実装→再テストのループ、終端は3値(APPROVED/NEEDS_HUMAN_REVIEW/ERROR)のfail-closed設計。NEEDS_HUMAN_REVIEW時はreview_report.mdを生成(Stage 2・spec §4-3/4-4) OrchestratorContextにdebug_retries/review_retries/terminal_state/review_reportフィールド追加(ループ状態の明示管理・spec §6-2)
Changed
main_cli.py:terminal_stateがNEEDS_HUMAN_REVIEWの場合、終了コードを2にマッピング(Stage 2・spec §4-4)
2026-07-18
Added
core/plan_contract.py: plan JSON の target_files 契約(検証・劣化モードフォールバック・パストラバーサル防止)- planner プロンプトに target_files 生成指示(path/role 契約)
main_cli.run_smoke_gate: 成果物の実在+py_compile 構文検査
Changed
- 実装フェーズ: hello.py 固定書き込みを廃止し、target_files に基づく複数ファイル生成に変更(生成済みファイルを existing_code で伝搬・空出力は RuntimeError)
- Smoke Test: hello.py 存在+”Hello”出力 → target_files 全実在+py_compile 構文チェックに再定義
run_full_projectが OrchestratorContext を返すように変更(既存呼び出しは非破壊)- README 自動生成: 固定文言を廃止し実際の生成ファイル一覧から組み立て
- plan パース堅牢化: dict / JSON文字列 / fence付き / 非JSON / None / 空文字 の各形態に対応(_coerce_plan)
Fixed
- CLAUDE.md のエージェント数 14→12(監査 C-1 関連のドキュメント整合)
- test_plan_contract の caplog 分離問題(フルスイート実行時の取りこぼし)
[8.2.5] - 2026-05-27
Changed
- 100行超関数の分割リファクタリング(36件→8件、78%削減)
- Phase 1:
test_generator_prompt.py,_builder.py,pr_comments.py,run_report_generator.py,code_prompt_tab.py - Phase 2:
fastapi_app.py,auth.py,github_self_healing_webhook.py,celery_app.py,views_logs.py - Phase 3:
github_pr_summary.py,notifier.py,views_projects.py,self_healing_service.py,orchestrator.py,semantic_diff.py,retry_utils.py,postmortem_agent.py,knowledge_curator_agent.py,unified_analyzer.py
- Phase 1:
- 各関数からヘルパー関数・定数を抽出し、メイン関数をオーケストレーター化
[8.2.4] - 2026-05-26
Fixed
fastapi_app.py: 本番環境でSESSION_SECRET未設定時にRuntimeErrorで起動拒否auth.py: OAuth例外時のエラー詳細をレスポンスに露出しないよう修正 + ロギング追加github_webhook_handler.py:repo_full_nameの形式検証追加(SSRF防止)fastapi_app.py: 汎用例外ハンドラにロギング追加graph_builder.py: リストアクセス時の境界チェック追加whisper_handler.py: 本番でエラー詳細を返さないよう修正(空文字列を返す)errors.py:classify_error()をテーブル駆動にリファクタリング(125行→55行)
Changed
errors.py:convert_http_error_to_nexus_error()を辞書マップ化(if-elifチェーン排除)- 211件の
# noqa: BLE001を精査 — 全て正当な広範キャッチと確認
Removed
sandbox_executor.py: 未使用import 3件削除(_CPU_TIME_LIMIT_SEC,_MEMORY_LIMIT_MB,_check_forbidden_modules)_checkers.py: 未使用importProjectType削除
[8.2.3] - 2026-05-26
Fixed
file_utils.py:"\\n"→"\n"バグ修正(エスケープ済み改行の二重エスケープ)unified_gradio_ui.py:run_test_handler重複定義削除context_analyzer.py: パストラバーサルガード追加(rel_path.startswith("..")チェック)_engine.py:.decode("utf8")→.decode("utf8", errors="replace")(デコードエラー保護)test_runner.py: コマンドインジェクション修正(shell=True→shlex.split()+ リスト形式)council_webui.py: Flask secret_key未設定時にRuntimeErrorで起動拒否unified_config.py: 本番secret_keyフォールバック無効化github_webhook.py: 本番Webhook署名スキップ拒否
Changed
- 125ファイルの bare except 全廃:
except Exception:→ 具体的例外型((json.JSONDecodeError, ValueError),(OSError, UnicodeDecodeError)等)または# noqa: BLE001 webapp/db_helpers.py: N+1クエリ解消(DB集計クエリ化)webapp/views_logs.py: メトリクス計算のインライン化webapp/views_dashboard.py: LLM統計のクエリ最適化- 為替レート 150.0 →
os.getenv("NEXUS_USD_JPY_RATE", "150.0") - Gradio URL →
os.getenv("NEXUS_GRADIO_HOST", "http://localhost:7860") - HTTP timeout 10 →
os.getenv("NEXUS_HTTP_TIMEOUT", "10")
Removed
views_dashboard.py: 未使用 import(PatchRecord, Project)views_logs.py: 未使用 import(desc)graph_builder.py: 未使用 import(sys)planner_agent.py,debugger_agent.py,_cache.py: 未使用 import(logging)
[8.2.2] - 2026-05-12
Fixed
- テストスイートハング修正:
pytest.iniのaddoptsに-m "not integration" --timeout=120を追加 —test_integration_llm.py(実際のLLM API呼び出し)をデフォルトで除外
Changed
- P1-1: APIルートのHTTPException判定を
isinstance(e, HTTPException)に統一、バックグラウンドタスクのエラー分類を追加(ValueError/ConnectionError/ImportError) - P1-2:
authority_runner.pyを3モジュールに分割(context.py,state.py,phase_logging.py)— 428→293行 - P1-3: LLMリトライロジック共通化 —
BaseLLM.execute_real_or_fallback()抽出、3プロバイダーを_build_real_call()クロージャパターンに統一 - P1-5:
GuardianAgentを2モジュールに分割(commit_workflow.py,review_executor.py)— 388→317行
[8.2.1] - 2026-05-11
Added
- P2-2: Settings UI Gradioタブ追加(
ui/settings_tab.py) — LLM プロバイダー状態・プロファイル情報・タスクルーティングの読み取り専用ダッシュボード - P2-3: フェーズ実行に tqdm 進捗バーとタイミングログを追加(
orchestrator/authority_runner.py) - P2-5:
webapp/db_helpers.py新規作成 — Webapp DBクエリ共通ヘルパー(13関数) - P2-1: subqueryload でN+1クエリ解消、DB count()クエリでPython集計排除
Changed
- P2-6: 12ファイルの未使用import除去(28→12、残りは意図的re-export)
- P2-4: 15ファイル160件の print()→logger 移行(残り37件は意図的)
- P2-5: views_projects/dashboard/logs の重複クエリパターンを共通ヘルパー化
Removed
orchestrator_inline.py: 5行スタブファイル削除(orchestrator_helper.pyに直接インポート)run_view.pydeprecated_router: 非推奨3エンドポイント(93行)削除、canonical_routerのみ残存requirement_agent.py: Gradio UI依存除去(TextLocalization / StateMachine / launch_gradio_ui / use_ui パラメータ)phase_runner_mixin.py:use_ui分岐(Gradio UI起動パス)削除dependencies/orchestrator.py:use_ui=Falseパラメータ除去fastapi_app.py: deprecated_router マウント除去
[8.2.0] - 2026-05-10
Added
- P1-1: GitHub OAuth認証ルーター(
api/routes/auth.py)をFastAPIで新規実装 — Starlette OAuthクライアント、SessionMiddleware対応
Changed
- P0-1:
_get_user_id_from_auth()のDRY解消 — 3ファイルの重複定義をdependencies/auth.pyに統合 - P0-1:
sandbox_executor.pyのハードコード値(メモリ/CPU制限)を環境変数化 - P0-2:
npe/budget.py,gemini_provider.pyの broadexcept Exception:を具体的例外型に修正 - P0-3:
deps/orchestrator.py→dependencies/orchestrator.pyに統合、deps/ディレクトリ削除 - P0-3(v2):
self_healing_service.py(1,006行)を3モジュールに分割(git_operations,test_runner,patch_workflow) - P0-4:
ProjectCreateRequestにパストラバーサル防止・URL検証のPydantic validator追加 - P1-2:
unified_gradio_ui.py(826行)を6モジュールに分割(_state, _llm_init, code_prompt_tab, ai_revision_tab, test_runner_tab, history_diff_tab) - P1-3:
orchestrator_inline.pyをorchestrator_helper.pyに統合、inline.py は後方互換re-exportのみ - P2-1:
orchestrator/explainability.pyにモジュール・関数docstringを追加 - P2-3:
utils/clean_output.pyにモジュール・関数docstringを追加 - P2-4:
api/utils/run_view.py→run_view_adapter.pyにリネーム(役割明確化)
Removed
- P0-2:
api/server.py(非推奨Flask 303行)をarchive/に移動。execute.pyのtasks参照をローカル変数に変更 - P2-2:
utils/math_ops.py(add()のみ、未使用)および関連テストを削除 - P1-1:
views_api_test.py(シミュレーションのみ)をarchive/に移動