CRW-152 · Go relay store: 스키마, 핵심 레코드, 나머지 도메인 - #171
thisisjun786 wants to merge 25 commits into
Conversation
Inventory of 117 non-test Python files mapped to CRW-150..161 owners with the process-spawn graph; scripts/port/check_inventory.py reconciles it with the tree.
CRW-140: 19 decisions, each with an Evidence line citing file:line or a URL.
CRW-140: 119 test files / 6,041 tests classified A/B/C with property, fixtures and Go destination; scripts/port/check_test_map.py reconciles counts with the tree.
CRW-150: go.mod (go 1.27, toolchain go1.27.1), staticcheck pinned at honnef.co/go/tools v0.7.0 via tools.go, Makefile build/test/contract/lint/dist with CGO_ENABLED=0 guard and empty-module skips.
…cts as data CRW-140: contract/schema/** generated by scripts/port/dump_contracts.py from the running Python (argparse tree, Store DDL and PRAGMAs, live MCP tools/list, App Server methods and bounds, hook and record shapes). --check regenerates and fails with a DIFF on any drift; the CLI count reconciles 144 top-level / 152 nodes / 140 call sites.
…ontract CRW-140: docs/port/cutover.md (ownership record, lock order, steps 0-7 with failure branches, same-DB rollback, rollback_allowed commit point, takeover inbox, hook budget, retention and its scan surface) and docs/port/control-group.md (8 CRW-116 + 19 CRW-124 scenarios transcribed verbatim from Linear, each with a Pass when line). scripts/port/check_cutover_doc.py enforces the sections, the scenario numbering and that no TTL or heartbeat authorises takeover.
CRW-150: cmd/crw dispatches on argv[0] (codex-session-relay, codex-thread-bridge, crw-completion-hook) then subcommand; internal/contract Emit reproduces Python json.dumps byte for byte (ordered maps, Python float repr) against Python-produced goldens; exit codes and 114 refusal reasons generated from contract/schema/relay-exit-codes.json; command registry with ContinueOnError flags (exit 4, nothing on stdout); scripts/port/check_json_emit.sh keeps JSON emission inside internal/contract. Makefile builds ./cmd/crw; staticcheck pinned to v0.8.1 for go1.27.
CRW-150: internal/bridge/appserver/fakehost speaks the App Server envelope over a unix-socket websocket (handshake as rpc.py: initialize then initialized; refused approval methods; 16 MiB frame limit, close 1009; frames with a jsonrpc member recorded as malformed), ported from the Python FakeServer in packages/codex-thread-bridge/tests/conftest.py. internal/testsupport carries the shared helpers. Adds github.com/coder/websocket v1.8.15.
CRW-150: .goreleaser.yaml (v2) builds ./cmd/crw with CGO_ENABLED=0 for linux/amd64, linux/arm64, darwin/arm64 into archives carrying crw, its three compatibility symlinks and both LICENSE files, with SHA256SUMS. release.yml gains release-go after the existing verification, gated like the other publish steps, and a snapshot build on the dry-run path. docs/releases.md labels darwin/arm64 built but unvalidated.
This reverts commit 9f518ae.
…thon build CRW-140 todo 6. contract/fixtures holds 350 scenarios run by contract/runner (hook, CLI, MCP, git, App Server, release, file observations) against the real Python programs, collected by both packages' test_contract_corpus.py through the repo-root conftest.py. Class-A tests that converted are thin runners over their fixture; each of the 555 class-A functions is recorded in contract/notes as converted, kept (live interleave, or mutation proofs moving to Go tests in todo 9) or blocked with the missing runner kind, and kept or blocked cases are Go test obligations of the owning todo named in docs/port/test-map.md. scripts/port/check_corpus_count.py enforces that coverage (criterion amended by Jun: behaviour coverage, not a fixture count). Relay CLI runs set HOME, XDG_* and CODEX_HOME to the scenario temp dir. Also registers the scripts/port check scripts added by todos 2, 3, 5 and 6 in docs/port/inventory.md, which todo 1's check had been missing.
CRW-150 todo 9. internal/contracttest finds the checkout through runtime.Caller(0), loads contract/fixtures/<domain>/*.json in place (no copies, no embedding) and runs registered kinds against the built crw (CLI argv and stdin; seeded SQL and row observations through modernc.org/sqlite). Domains and kinds without a Go implementation are explicit skips, counted and printed as 'skipped: <n> domains not ported'; CRW_CONTRACT_STRICT=1 turns any skip into a failure naming the domains. No domain is registered as ported yet.
CRW-152 todo 17. internal/relay/store opens the relay database with the frozen contract/schema/relay-sqlite.sql embedded byte-for-byte (a test compares it with the contract file), the guard indexes derived from it, foreign_keys/WAL/synchronous=FULL/busy_timeout on every pooled connection, insert-or-ignore identity rows, and a refusal to open the live host state directory (symlinks resolved). State-directory selection (--state, CODEX_SESSION_RELAY_STATE, XDG_STATE_HOME, socket hash, legacy sibling adoption) and Locate follow the Python resolve_state_dir, discover_state_dir and locate, checked against the real Python, including '..' spellings, symlinks and an unknown ~user (an error, as pathlib raises). The sqlite-ddl corpus domain now checks the DDL, a committed Python-created database (scripts/port/make_sqlite_fixture.py), the pooled PRAGMAs and lock behaviour in both directions. test_store.py properties move to todo 18 in docs/port/test-map.md.
…ath job Todo 11 (997cae8) added two class-A test_release.py functions and three other CI test functions and grew scripts/ci/scope.py by a line without updating the port maps, so check_test_map, check_corpus_count and check_inventory failed on this branch. The two release-workflow tests are kept in Python with todo 47 as their Go owner; the counts and the scope.py line are updated. All three checks exit 0.
# Conflicts: # docs/port/inventory.md
CRW-152 todo 18. internal/relay/store gains typed record functions for relationships, generations, events, deliveries, attempts, acks, verdicts, journal and receipts; the full Python receipt intake (refusal reasons, turn admission, contradiction checks, staging, daemon observations, recorded refusals); artifact reads that refuse symlinks, read twice and detect relocation; the registry's set-status, supersede, open-generation and bind-anchor with a relationship record byte-identical to Python's; and store identity (locate, probe, nonce lookup, challenge) in Python's check order. The store keeps one SQLite connection (docs/port/decisions.md section 4). Transaction carries the open transaction in the context: a nested Transaction is refused at once, Compose joins, and every read goes through the transaction's connection so it sees uncommitted writes, as Python's single connection does. Behaviour parity: 172 of the 178 owned Python tests are equivalent Go tests; 6 depend on the delivery service and are deferred to todo 21 with their store half tested here. Persisted records are validated with the repository's Python jsonschema, so the go-product CI job now syncs the uv workspace before running the Go tests.
… without pytest Plan item 15b, found by CI on PR #170 and failing identically on #168 and #169 while dev was green: - validate: wave 0 edited packages/*/tests without re-deriving scripts/crw_runtime/components.json, so verify-definition reported both subdirectoryTree values stale; they are re-derived with git rev-parse HEAD:packages/<name> as docs/runtime-install.md describes. The install KeyErrors in scripts/ci/tests followed from the same stale definition. - tests: contract/runner imported pytest at load time and loaded stopadapter through the relay package; the offline scripts/ci/tests job has neither. pytest.fail becomes AssertionError and stopadapter.py is loaded from its file, as the pre-wave-0 test did. The CI job itself is unchanged (POLICY.md: standard-library checks). - dev-gate: contract/, docs/port/ and conftest.py had no verification mapping; they are registered for full coverage because tests and scripts/port checkers read them. Verified in a clean copy under a Python 3.10 venv without pytest: scripts/ci/validate.py, contracts.py, plugin.py and python3 -m unittest discover -s scripts/ci/tests each exit 0.
# Conflicts: # docs/CI.md # scripts/ci/scope.py
CRW-152 todo 19. internal/relay/store gains typed queries for the 59 tables the core records left out (linkage, merge-turn, capacity, edit regions, managed start, supervisor channel, sync, product routing and the fault ledger): 209 methods, each naming the Python store/domain line it reproduces, keeping its columns, ORDER BY, conflict clause and literal defaults. Every write and read goes through the transaction-aware querier. TestEverySchemaTable_has_a_go_query_referencing_it parses the embedded schema (84 tables; the plan's 90 counted CREATE TABLE inside comments, checked against sqlite_master) and fails for any table without a Go query. Ten parity tests read stores written by the real Python relay, one per domain group, and compare every column. Guard indexes: under racing threads Python's writers refuse, queue or replay before any of the six partial-unique indexes is reached; only a raw INSERT reaches one, and Python then raises sqlite3.IntegrityError (2067, "UNIQUE constraint failed: ..."). Go returns the same driver error, and each TestGuard_<index>_fails_like_python drives Python into that index first. Independent checker confirmed round 2 (3/3 mutations caught after 11/13 in round 1). Clean copy: uv sync --locked, make lint, make test, make contract and check_test_map each exit 0.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Superseded by #172 (merge 186ac7a). Merging current dev into this branch (7defe34) produces a tree identical to dev: every change here, including the final store-domains merge (test_scope.py, components.json), already landed through the wave-2 integration branch. Closing instead of merging an empty change. Verified locally: go build, race suite over internal/relay and contracttest, and scripts/ci/tests/test_scope.py pass on that tree. |
There was a problem hiding this comment.
Devin Review found 2 potential issues.
🐛 2 issues in files not directly in the diff
🐛 Fault target updates mix teams and projects
When concurrent callers use SetFaultTarget without a transaction, their two upserts can interleave. The stored team can belong to one target and the project to another.
🐛 Concurrent incidents lose their route order
When callers use StoreRouteIncident concurrently without a transaction, both can calculate the same recorded_seq. Later incident listings and pruning cannot reliably identify the newest input.
CRW-152 · crw-go-port wave 2의 store 트랙입니다. #169(CRW-150) 위에 쌓인 브랜치라서 #168 → #169 다음에 병합되어야 합니다.
포함된 todo
a1dde24e핵심 relay 레코드, receipt 수신, 스토어 식별de10fc15나머지 도메인 테이블 84개 전부에 대한 Go 쿼리와 가드 인덱스 동작검증
각 todo는 워커 구현 → 독립 checker → 오케스트레이터 재실행 → 단일 커밋 순서로 들어왔습니다. 이 브랜치 끝(7defe34)의 클린 카피에서
uv sync --locked,make lint,make test,make contract,check_inventory,check_test_map,check_corpus_count가 모두 exit 0이었고, 워크트리에서scripts/ci/validate.py,contracts.py,plugin.py도 exit 0이었습니다.todo 19에서 확인한 것: Python writer는 여러 스레드가 경합해도 가드 인덱스까지 가지 않고 거절·대기·재생합니다. raw INSERT만 인덱스에 닿고, 이때 Python과 Go 모두
IntegrityError2067을 냅니다. 그래서 Go도 거절 사유로 바꾸지 않고 드라이버 오류를 그대로 돌려줍니다.남은 일
todo 20(doctor, store identity, show, status)은 통합 기반에서 수정 라운드 중입니다. 완료 전까지 draft로 둡니다.
Plan: .omo/plans/crw-go-port.md