Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/setup-python@v7
with:
python-version: "3.11"
Expand Down
1 change: 1 addition & 0 deletions docs/Decision-Structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ edge target は Decision Structure node slug とする。外部資料は `Edges`
- lowercase kebab-case の Decision Structure entry と `_Sidebar.md` は Wiki-only である。docs-to-Wiki synchronization は、`docs/` に対応物がないことを理由にこれらを create、overwrite、delete しない。
- 個別 Wiki entry は、その判断の current state の正本である。GitHub issue、pull request、commit、test output、fixture、gold、manifest、gate、result artifact は、それぞれの所有境界に従う根拠または契約であり、リンクしただけで Decision Structure entry にはならない。
- `requirements.md`、実験文書、fixture、gold、manifest、gate、result artifact は、既存の source-of-truth boundary を維持する。
- frozen source / artifact hash の source of truth は、manifest path の初回追加 commit または manifest が明示する lowercase full 40-hex source commit の exact blob bytes である。後続の committed manifest rewrite や mutable ref は信頼境界を動かさず、current working tree の同名 path は後続 evolution の現在状態であって historical evidence ではない。

## Lifecycle

Expand Down
2 changes: 1 addition & 1 deletion docs/blind-llm-channel-selection-experiment.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ Development gateは不合格であり、`holdout_status=not_opened_invalid_judge

PR #22の最初のLinux CI run `30731318651`では、Windowsでfreezeしたv1 text artifactのCRLF checkout byte hashと、GitHub ActionsのLF checkout byte hashが一致せず、`d1_liplus_channels.contamination.json`のfreeze auditで停止した。内容差ではなく、Gitのtext checkout変換だけが原因である。

その後、mainから作成したfresh Windows worktreeでは、v2 judge prompt、development packet、judge artifactもLFの固定hashに対してCRLFでcheckoutされ、同じ内容のままmanifest読込とobserved artifact auditが停止した。verificationをv1だけに限定すると同じfrozen text契約をv2へ一貫して適用できないため、v1 / v2 frozen text-byte verificationを次の順序へ揃えた。
その後、mainから作成したfresh Windows worktreeでは、v2 judge prompt、development packet、judge artifactもLFの固定hashに対してCRLFでcheckoutされ、同じ内容のままmanifest読込とobserved artifact auditが停止した。verificationをv1だけに限定すると同じfrozen text契約をv2へ一貫して適用できないため、v1 は manifest が明示する full baseline commit ID、v2 は manifest path の初回追加 commit の blob bytes を取得し、frozen text-byte verificationを次の順序へ揃えた。current working tree の同名 path は historical evidence に使わない

1. checkout raw bytesのSHA-256を最初に照合する。
2. raw不一致時だけ、全改行がLF一種類ならCRLFへ、CRLF一種類ならLFへexact変換する。
Expand Down
2 changes: 2 additions & 0 deletions docs/engine-backed-feedback-trajectory-experiment.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ repository-native controlled corpus v3 に対し、実際の `NeuronGraphRAG` in
- Audit: `tests/fixtures/engine_feedback_trajectory_v3.audit.json`
- Manifest: `tests/fixtures/engine_feedback_trajectory_v3.manifest.json`

manifest artifact は manifest path の初回追加 commit、source corpus は上記 source corpus commit の exact blob bytes を読む。各 commit の存在と current `HEAD` の ancestor 関係を検証し、current working tree の同名 fixture、source document、evaluator は historical evidence として扱わない。既存の raw-first LF / CRLF whole-file alternate だけを維持する。

development は `signal-stability` と `boundary-recovery`、holdout は `evidence-continuity` を使う。node ID、document path、source URL、explicit-link edge は split 間で重複させない。edge は overview 文書に記載された同一 directory 内の相対 Markdown link だけから固定する。

result-free commit を push するまで development と holdout の runner を実行しない。exclusive output が存在しないことを audit に固定し、runner は既存 output の上書きを拒否する。
Expand Down
2 changes: 2 additions & 0 deletions docs/feedback-policy-comparison-evaluation.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

protocol ID は `policycmp85-feedback-policy-comparison-v1` である。fixture、gold、query、cohort role、graph projection、engine config、event order、checkpoint、metric、gate array、result schema、exclusive writer、verifier、output path を observed result 不在の freeze commit に固定して push する。

protocol artifact hash は manifest path の初回追加 commit の exact blob bytes に対して照合し、検証後の fixture、gold、schedule、gate、schema、audit も同じ初回登録 blob から読む。current working tree の同名 evaluator、test、README、docs は後続 evolution であり、過去の protocol bytes として扱わない。source corpus は引き続き manifest の lowercase full 40-hex `source_commit` にある manifest と文書の exact bytes だけを読む。

development は Amber を `confirmed-use`、Cobalt を `corrected-use` に割り当てる。全 hard gate 通過時だけ開く holdout は Quartz を `confirmed-use`、Willow を `corrected-use` に割り当てる。split 間では node、path、source URL、edge identity、query を共有しない。各 arm は同じ split の8文書、6 edge、query、event order を使う。

freeze 前の writer/verifier 検査は、登録 query、gold、node、output path と無関係な placeholder identity を temporary directory に exclusive create し、非アルファベット順 field の UTF-8 semantic round-trip を確認して削除する。登録 output は freeze 時に存在せず、writer は `O_EXCL` だけを使う。観測後の再実行、上書き、再集計、field reorder、query/gold/ratio/gate の変更を禁止する。
Expand Down
20 changes: 20 additions & 0 deletions docs/historical-source-verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Historical source verification

## 目的

frozen evaluation の hash registry は、過去の protocol を固定した時点の bytes を証明する。後続の正当な repository evolution を拒否せず、現在の working tree を過去の evidence と取り違えない。

## Source-of-truth boundary

- manifest 内の artifact hash は、その manifest path を最初に追加した登録 commit にある `git show <commit>:<path>` の exact bytes と照合する。後続の committed rewrite を新しい信頼点にせず、current manifest bytes 自体が初回登録 blob と一致することを先に検証する。
- manifest が source commit、baseline commit、prior commit を明示する source registry は、その明示 commit の blob を照合する。明示 commit は lowercase full 40-hex object ID に限定し、branch、tag、`HEAD~1` 等の mutable ref / revision expression を拒否する。
- commit object が存在し、現在の `HEAD` の ancestor であることを必須とする。未知 commit、非 ancestor commit、欠落 path、hash 不一致、working-tree manifest 改変は fail closed にする。
- 同名 path の current working-tree bytes は historical evidence ではない。検証後に evaluator が frozen fixture、gold、schedule、gate、source document を読む場合も、検証済み commit blob を使う。

## Newline contract

既存 protocol が raw-first の LF / CRLF portability を明記している場合だけ、raw blob hash 不一致後に whole-file LF -> CRLF または CRLF -> LF の一回の exact 変換を許す。本文差、mixed newline、bare CR、その他の byte 差は許可しない。明記のない registry は exact raw bytes だけを受理する。

## 非変更範囲

この境界修正は frozen manifest、fixture、packet、snapshot、observed result、登録 hash、source commit、観測回数、metric、gate、解釈を変更・再実行・再集計しない。変更するのは hash verifier が bytes を取得する時点だけである。
5 changes: 4 additions & 1 deletion docs/real-task-feedback-shadow-protocol-v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ local exact verifier は明示された SQLite snapshot を必要とする。liv

repository lifecycle audit は repository 内 artifact だけを使い、snapshot replay を担当しない。次を検証する。

- protocol / legacy frozen artifact hash
- v3 manifest path の初回追加 commit にある protocol / legacy frozen artifact の exact blob hash
- 初回追加 commit の存在と current `HEAD` の ancestor 関係、および current manifest bytes と初回登録 manifest bytes の一致
- packet と aggregate の canonical JSON bytes
- root slot の連番、correction chain の到達可能性、immutable correction field
- effective packet 全体で共通の snapshot hash、capture config、search surface と、slot 順に厳密増加する capture timestamp
Expand All @@ -59,3 +60,5 @@ python tools/run_real_task_shadow_v3.py audit-lifecycle --manifest tests/fixture
```

`probe` は実 MCP adapter search から placeholder packet、snapshot exact verification、two-arm replay、one-time result までを一時 directory 内で一巡し、registered output を repository に生成しない。`audit-lifecycle` は snapshot を使わず、freeze 後の repository lifecycle state を検証する。

同名 path の current working tree は repository evolution の現在状態であり、v1 / v2 / v3 の historical evidence ではない。lifecycle audit は manifest、packet、aggregate、gate、観測結果を変更せず、hash 取得元だけを manifest path の初回追加 commit の blob に固定する。
2 changes: 2 additions & 0 deletions docs/requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
79. repository-native controlled corpus v3 の engine-backed trajectory experiment は、source commit、split / cluster identity、explicit-link edge、0 / 1 / 3 / 10 feedback schedule、query、used node、credited path、control / treatment、gate、manifest hash、exclusive output を観測前に固定する。control は relation trace と used node を記録して edge を変更せず、treatment だけが同じ schedule の relation trace ID を `record_success` に渡す。headroom は 0 から 10 で厳密改善し途中 checkpoint で退行せず、control case と ceiling case も退行せず、credited edge 以外が変化しない場合だけ development gate を通過する。development 全 gate 通過時だけ holdout を一度開き、観測後は evaluator、fixture、gold、schedule、manifest、gate、docs を変更しない。
80. sibling relation feedback normalization は、明示的に有効化された candidate config でのみ、relation trace の credited edge を強化し、その edge と同じ source から出る未 credit sibling だけを局所的に正規化できる。lexical trace、zero-hop、未関係 source、credited sibling は変更しない。candidate は synthetic isolation test と result-free development / holdout 相当の relation、direct、lexical、negative-control gate を通過するまで default にしない。
81. sibling normalization controlled evaluation は、評価対象 source commit / hash、相互に identity-disjoint な development / holdout cluster、明示 edge、baseline `0.0` / treatment `1.0`、query、used node、credited path、mutation scope、rollback、係数 / 時刻 schedule、hard gate、exclusive output を観測前に固定する。実 `NeuronGraphRAG` の `search_channels` relation trace ID を `record_success` に渡し、headroom strict improvement、ceiling・direct・lexical・directional-negative non-regression、path・mutation・atomicity・determinism の全 development gate 通過時だけ holdout を一度開く。観測後は protocol artifact と docs を変更せず、既定値と external D1 claim を変更しない。
82. frozen evaluation の historical source hash は、manifest path の初回追加 commit または manifest が明示する lowercase full 40-hex source / baseline / prior commit の exact blob bytes に対して検証する。後続の committed manifest rewrite、mutable ref / revision expression、未知 commit、非 ancestor commit、manifest bytes差、欠落 path、hash 不一致を fail closed にし、同名 path の current working tree を過去の evidence として扱わない。既存 protocol が明記する raw-first LF / CRLF whole-file alternate だけを維持し、本文差、mixed newline、bare CR、その他の byte 差を拒否する。
75. v3 implementation、prompt、manifest、query override、schema、集約、path audit、hash規則、gate、stop rule、testsをresult-free commitでpushした後、development stage / 4 case packet / 12 responses / resultを各一度だけ生成する。
76. development全12 gate通過時だけholdout stageを一度生成し、異なるfresh 12 judgesで同じgateを評価する。packet、response、resultの上書き、観測後の規則変更、実LLM品質値のCI再生成を拒否する。

Expand Down Expand Up @@ -132,3 +133,4 @@
- [Engine-backed feedback trajectory experiment](engine-backed-feedback-trajectory-experiment.md) が repository-native controlled corpus v3 上の 0 / 1 / 3 / 10 feedback trajectory、実 relation trace、credited-only mutation、result-free freeze、conditional holdout を定義する。
- [Sibling relation feedback normalization](sibling-relation-feedback-normalization.md) が opt-in candidate の局所 sibling 正規化、trace isolation、default 変更前の検証境界を定義する。
- [Sibling normalization controlled evaluation](sibling-normalization-controlled-evaluation.md) が repository-native corpus、result-free hash freeze、実 relation trace feedback、mutation / rollback gate、conditional holdout を定義する。
- [Historical source verification](historical-source-verification.md) が frozen manifest path の初回追加 commit、明示 full source commit ID、exact blob、ancestor、path、newline portability、fail-closed 境界を定義する。
2 changes: 2 additions & 0 deletions docs/sibling-normalization-controlled-evaluation.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

`sibling_normalization_controlled_v1` の fixture、gold、schedule、manifest、gate、evaluator、runner、test と本書を、observed output が存在しない状態で commit / push する。manifest は評価対象の engine source commit と SHA-256、登録 artifact の SHA-256、split / cluster identity、exclusive output path を固定する。

評価対象 engine source は manifest の明示 full commit ID、protocol artifact は manifest path の初回追加 commit の exact blob bytes を読む。commit の存在と current `HEAD` の ancestor 関係、manifest bytes、path、hash を検証し、current working tree の同名 path は historical evidence として扱わない。

development と holdout は node ID、cluster ID、query 語彙を共有しない。過去の feedback trajectory evaluator、fixture、gold、schedule、manifest、gate、observed result は選択入力にも実行入力にも使わない。

登録 runner は clean worktree かつ `HEAD == upstream` の freeze 後だけ実行できる。既存 output の上書きを拒否し、development が全 hard gate を通過した場合だけ holdout を一度開く。失敗結果も保存し、protocol 調整や再実行を行わない。
Expand Down
30 changes: 19 additions & 11 deletions src/neuron_graph_rag/blind_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
from pathlib import Path
from typing import Any, Iterable

from .corpus_integrity import (
verify_historical_source_hashes,
verify_manifest_source_hashes,
)
from .d1_fixture import load_fixture
from .engine import EngineConfig, NeuronGraphRAG

Expand Down Expand Up @@ -45,12 +49,15 @@ def read_blind_manifest(path: str | Path) -> dict[str, Any]:
if len(manifest.get("gate", [])) != 12:
raise ValueError("Blind selection manifest must freeze twelve gates")
_audit_v1_hashes(manifest_path, manifest)
prompt_path = _repo_root(manifest_path) / manifest["judge_prompt"]["path"]
if not _matches_frozen_text_bytes(
prompt_path, str(manifest["judge_prompt"]["sha256"])
):
raise ValueError("Frozen judge prompt hash mismatch")
_validate_prompt(prompt_path.read_text(encoding="utf-8"))
root = _repo_root(manifest_path)
prompt_relative = str(manifest["judge_prompt"]["path"])
prompt = verify_manifest_source_hashes(
root,
manifest_path,
{prompt_relative: str(manifest["judge_prompt"]["sha256"])},
allow_text_newline_alternate=True,
)
_validate_prompt(prompt.artifact_bytes[prompt_relative].decode("utf-8"))
return manifest


Expand Down Expand Up @@ -560,11 +567,12 @@ def _audit_v1_hashes(manifest_path: Path, manifest: dict[str, Any]) -> None:
entries = manifest.get("frozen_v1_bytes")
if not isinstance(entries, list) or not entries:
raise ValueError("Blind manifest must freeze v1 byte hashes")
for entry in entries:
if not _matches_frozen_text_bytes(
root / entry["path"], str(entry["sha256"])
):
raise ValueError(f"Frozen v1 byte hash mismatch: {entry['path']}")
verify_historical_source_hashes(
root,
str(manifest["frozen_v1_baseline_commit"]),
{str(entry["path"]): str(entry["sha256"]) for entry in entries},
allow_text_newline_alternate=True,
)


def _matches_frozen_text_bytes(path: Path, expected_sha256: str) -> bool:
Expand Down
Loading