Repository navigation
feat(#536): run completion for saccade_track (CC-536-01-01) - #562
Merged
Merged
Conversation
Run id on stderr's first line; non-blocking exclusive flock on <out>; journal saccade.native_track_journal/v1 (running/failed/complete, per sequence pending/written with sha256) installed by temp+rename before this run's earlier report / txt / trace files are removed; txt and trace temp+rename, journal written after each; report then state=complete as the only commit point. Report format v3 (v2 + run_id + identity level null); native_track_parity pins v3 and judges the journal by the caller rule. CUDA-free protocol test with real SIGKILL kill points and a second process; real-binary CLI tests without a GPU. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A mutant that removed the new journal during the cleanup survived the earlier cases (the next commit rewrote it); this case observes the window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Archive the outgoing canonical (implementation 3d85835ce4814d72, the #552 review-fix publication) and promote a fresh capture from the controlled host (build/runtime_identity, Release, --run-probe --require-complete) at the implementation head 006007d. Axes: * implementation MOVED 3d85835ce4814d72 -> 6848dfaa31137ba2; files 290 -> 292. - Added (2): shipping/include/saccade_shipping/run_completion.hpp, shipping/src/run_completion.cpp (run id, <out> lock, journal, temp -> rename, the complete commit point; CC-536-01-01). - Changed (4): shipping/CMakeLists.txt (saccade_shipping_completion and its CUDA-free test), shipping/tools/track_driver.hpp (commits through RunCompletion; report v3), shipping/tools/saccade_track.cpp and shipping/tools/saccade_track_measurement.cpp (begin_run; failed journal on a caught error). - Removed: none. * environment, decision_surface, identity_semantics, runtime_inputs: unchanged. * probe: re-run fresh, not reused. Behavior 2dabed0b, equal to the previous publication. The build witness moved because build/runtime_identity was reconfigured (cmake -S . -B) before the build. Probe equality is not an equivalence claim; equivalence stays unproven. check_runtime_identity_staleness.py --mode attested: exit 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Runtime-coordinate republication (stacked): see the PR above whose base is |
Owner
Author
|
Stacked republication: #563. |
Owner
Author
|
CI on |
…ads the run id from line 1 only #562 review P2/P3 (reader and tests only; the shipping implementation coordinate is unchanged). P2: journal_problems() parsed the journal with a bare json.loads, so a journal that exists but is not JSON raised instead of returning problems (the run would not be judged UNRESOLVED through the diagnostic contract). It now returns a problem for an unreadable / non-JSON journal, a top level that is not an object, and `sequences` that is not a list of objects; a `report` that is not an object counts as unrecorded. committed_sequences() returns [] for the same malformed `sequences`. P3: invocation_run_id() accepted a unique run_id line anywhere in the log. It now takes the run id only from the log's first line (the writer's first stderr line; the log has no stdout before it) and still refuses a log with any other run_id line, of either entrypoint. Negative controls: 8 corrupt journal texts, 6 malformed `sequences`, 3 malformed `report`, and leading-line / second-entrypoint run id logs; 18 of them fail on the previous reader. The 10 saccade_track.log files of the local GPU runs (results/536_completion/runtime_006007d3) all still yield their run id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chore(provenance): republish the runtime coordinate for #536 Completion
This was referenced Oct 10, 2026
Open
architecture(B): design a supported architecture with traceable diagrams and behavior contracts
#536
Open
This was referenced Oct 10, 2026
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
#536 Completion 切片(CC-536-01-01),依 owner 授權從
main@f7d4e1e8起。僅供審查,不要 merge。 契約狀態與 #550 checkpoint 的回寫留到 merge 並通過主線驗證之後。run_id(getrandom128 bit,32 hex),stderr 第一行saccade_track: run_id <id>;journal 與 report 都帶它。參數被拒時不產生 run id,也不建立任何檔案(與既有rejected檢查一致)<out>/saccade_track.lock上非阻塞flock(LOCK_EX|LOCK_NB),持有到 process 結束;衝突時 exit 2,不寫 journal、不刪檔。lock 檔不刪除<out>/saccade_track.journal.json,formatsaccade.native_track_journal/v1:staterunning/failed/complete;依 argv 順序的每個 sequence 狀態pending/written,含 txt 與 trace 的 sha256;report {path, sha256};failure {sequence|null, message};identity {"level": null}.<name>.<run_id>.tmp)→ fsync → rename → fsync 目錄。journal 只在 rename 之後才改成writtenstate=complete(最後一次寫入)<out>(含不存在的父目錄)→ lock → 以 temp+rename 安裝新 journal → 之後才作廢本輪的--report、<out>/<seq>.txt、<trace>/<seq>/detector.bin。新 journal 與 lock 在建立任何東西之前就先排除在作廢清單外:輸出路徑若撞到它們,會在<out>建立前被拒saccade.native_track_report/v3= v2 加run_id與identity。v2 語義不變;native_track_parity.py改釘 v3,並依 caller rule 判讀 journalsaccade_track_measurement的介面與 surface 不變程式碼:
shipping/{include/saccade_shipping,src}/run_completion.*(CUDA-free,只用 std filesystem、POSIX、strict_json、sha256),track_driver.hpp的begin_run/run_sequences透過RunCompletion::run提交;兩個 entrypoint 的main持有std::optional<RunCompletion>,錯誤處理寫入failed。負控制
CUDA-free 協定測試:
tests/native/test_shipping_run_completion.cpp,181 checks,跑在既有的shipping-config-loaderctest job,沒有改 workflow。每個 case 都在 fork 出來的子 process 執行真正的RunCompletion::run,所以 kill 是真的SIGKILL、第二個 run 是真的第二個 process。kill point 只在測試 target 以SACCADE_RUN_COMPLETION_TEST_FAULTS編入;shipping 與 measurement build 會把它們編譯成空。failed_rerunrun_id、failed,failure.sequence是失敗的那個、message 相同;前面的 sequence 已written,內容是重跑的位元組;後面的 sequencepending,舊 txt 與 trace 已刪除;<out>內其他檔案未動failed_rerun、killed_in_*<out>外的舊 report 已作廢;舊run_id不再命名任何東西lock_busyrun_id;持有者被 SIGKILL 後由 kernel 釋放 lockfailed_rerun(throw)、killed_in_sequence(SIGKILL)failed/running;被中斷的 sequence 為pending,沒有 txtkilled_after_renamepending,caller rule 不算它。另有killed_before_rename(只有 temp 檔)與killed_after_report(report 已在,但不是complete)<out>原本不存在freshkilled_in_first_sequence、collisionspending;--report指向 journal、lock、<seq>.txt、trace 檔,或經..別名指向它們時,都在<out>建立前被拒;--report位置是目錄時 run 失敗,目錄保留Mutation 檢查(本機,非 CI;raw 輸出在
results/536_completion/mutation_006007d3/):12 個 mutant,每個至少讓一項檢查失敗:journal 在 rename 之前寫、直接寫入正式路徑、不取 lock、不作廢、保留舊 report、complete寫在 report 之前、作廢在 journal 之前、作廢時刪掉新 journal、拿掉碰撞檢查、fail不記 sequence、lock 衝突時仍寫 journal、建構子失敗不記錄。「作廢時刪掉新 journal」一開始沒被抓到(下一次 commit 會重寫 journal),所以加了killed_in_first_sequence(commit006007d3)。每個 mutant 後都以git checkout還原,並比對 sha256 確認。Reader↔writer:
tests/unit/test_native_track_parity.py以--keep跑上述測試,再用native_track_parity的committed_sequences/journal_problems判讀 writer 真正留下的檔案;另有合成 journal 的 fail-closed 測試,涵蓋錯誤 run_id、running/failed、pending但檔案存在、sha 不符、trace/report 被替換、identity 升級。真 binary、不需 GPU(
tests/unit/test_saccade_track_completion_cli.py,以及修改後的test_saccade_track_schedule_cli.py;未 build 時 skip):run_id 是第一行且每次不同(兩個 entrypoint 都測);用外部fcntl.flock佔住<out>時 exit 2,所有檔案不變;--report指向 journal 時在<out>建立前被拒;失敗重跑會刪除舊 report 與本輪的舊 txt,其他 sequence 的 txt 保留。Runtime 證據(GPU,本機,非 CI)
results/536_completion/runtime_006007d3/(gitignored),commit006007d3,工作樹乾淨(前後都是),全部在 gpu0 lease 下依序執行(run.sh)。op libraryaa84cccd…前後都等於 attestation。binary 是build-release/shipping/(-DSACCADE_WITH_OPENCV=OFF,PR-C2 的 arch list)。parity,shipping、double buffer、7 序列、含 trace,--againstPR-C2 正式 run(full_276659a8/parity_host)against.identical=true:txt、trace hash 與 graph 計數完全相同。report v3,identity {"level": null},journal 沒有 problemnone--against上一列--schedule serial--againstPR-C2 serialref_edit)complete,沒有 problem<out>(第二個 sequenceMOT17-99-SDP不存在)failed,failure.sequence=MOT17-99-SDP;MOT17-09 已written,位元組與 R1 相同;舊 report 已刪除;MOT17-02(不在本輪)未動written之後 SIGKILLrunning;只有 MOT17-09 committed;沒有 MOT17-02 txt,也沒有 reportCI 與 runtime coordinate
shipping/**屬於decision_relevant,所以implementation軸會移動(290 → 292 檔)。只有這支 PR 時pytest會被 6 個 coordinate-bound contract test 擋下,這是預期的閘門,不是功能壞掉。Republication 依 runbook §3.2 走 stacked PR(base = 本 branch),連結見下方留言;其餘軸不變,probe 重新抓取(behavior2dabed0b,與先前相同;equivalence 仍是unproven)。本 PR 不做的事
沒有 Preflight/Gate A:hash 與輸入檢查仍在 GPU 初始化之後(G2)。沒有 Identity integration:
identity.level一律是null,沒有expected_source_verified,也沒有 binding 清單(CC-536-01-02)。不改模型、numerics、MOT 行為、parity 標準或 required CI workflow。發行維持 local-only,#547 不變。不新增狀態轉換語義(#537),也不新增 contract→check 文件(#541)。Known limits
shipping/entrypoint_pin.json仍是 PR-C2 的 bytes,所以以SACCADE_SHIPPING_ENTRYPOINT打包的 tree 仍是沒有 completion 的舊行為。shipping/package/README.txt也沒有改:tree 內的 README 必須與 source 位元組相同,而在 pin 更新之前描述 completion 會不正確。連帶的,對 pinned package 跑native_track_parity --native-from,現在會得到UNRESOLVED(v2 report,沒有 journal)。卡片要求把作廢的行為變更寫進 package README,本 PR 只寫在 CLI 說明,README 等 re-pin 時再改。重新 pin(含 README 與正式 run)需要另一次授權。<out>以外的--report/--trace不受 lock 保護。現有保護:每個 run 的 temp 檔名不同,加上 rename,所以不會出現寫到一半的檔案;report 帶run_id;journal 記錄 report 與每個 trace 的 sha256。只有 journal 記錄、而且 hash 相符的檔案才算數(已有測試)。用不同<out>、但共用 report 或 trace 的兩個並行 run 不會被排除,後 rename 的那個勝出,另一個會被 hash 不符偵測到。.<name>.<run_id>.tmp,不會自動清理(作廢只處理本輪的正式路徑)。running。<out>會留下 lock 與failedjournal(以前不會建立<out>);test_saccade_track_schedule_cli.py的斷言已據此修改。🤖 Generated with Claude Code