Repository navigation
[DONE] 정리 4단계 PR 17 — MIDI 받는 쪽 벡터 아홉 개가 가상 패널에서 돌고, check:midi-vectors 가 PR 마다 본다 - #87
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UYMwmokDNM7DPd588Afarz
k17 of the step 4 plan: nine vectors of midi-spec.md's host → device table, replayed against the virtual panel through an RTP-MIDI initiator of their own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UYMwmokDNM7DPd588Afarz
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UYMwmokDNM7DPd588Afarz
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UYMwmokDNM7DPd588Afarz
patternflow-bot
marked this pull request as ready for review
October 15, 2026 16:31
10 tasks done
engmung
pushed a commit
to engmung/Patternflow
that referenced
this pull request
Oct 15, 2026
engmung
pushed a commit
to engmung/Patternflow
that referenced
this pull request
Oct 15, 2026
Patternflow-lab#11 Patternflow-lab#12 Patternflow-lab#13 Patternflow-lab#15 Patternflow-lab#17 Patternflow-lab#14 Patternflow-lab#16 Patternflow-lab#19 Patternflow-lab#20 Patternflow-lab#18 Patternflow-lab#21 Patternflow-lab#23 Patternflow-lab#24 Patternflow-lab#25 Patternflow-lab#26 Patternflow-lab#28 Patternflow-lab#29 Patternflow-lab#30 Patternflow-lab#27 Patternflow-lab#31 Patternflow-lab#32 Patternflow-lab#34 Patternflow-lab#35 Patternflow-lab#33 Patternflow-lab#36 Patternflow-lab#37 Patternflow-lab#38 Patternflow-lab#39 Patternflow-lab#40 Patternflow-lab#41 Patternflow-lab#42 Patternflow-lab#43 Patternflow-lab#46 Patternflow-lab#44 Patternflow-lab#47 Patternflow-lab#48 Patternflow-lab#49 Patternflow-lab#45 Patternflow-lab#50 Patternflow-lab#51 Patternflow-lab#52 Patternflow-lab#54 Patternflow-lab#57 Patternflow-lab#55 Patternflow-lab#53 Patternflow-lab#56 Patternflow-lab#59 Patternflow-lab#58 Patternflow-lab#60 Patternflow-lab#61 Patternflow-lab#62 Patternflow-lab#63 Patternflow-lab#64 Patternflow-lab#65 Patternflow-lab#66 Patternflow-lab#67 Patternflow-lab#68 Patternflow-lab#69 Patternflow-lab#70 Patternflow-lab#72 Patternflow-lab#73 Patternflow-lab#71 Patternflow-lab#75 Patternflow-lab#74 Patternflow-lab#77 Patternflow-lab#78 Patternflow-lab#76 Patternflow-lab#79 Patternflow-lab#80 Patternflow-lab#81 Patternflow-lab#82 Patternflow-lab#84 Patternflow-lab#83 Patternflow-lab#85 Patternflow-lab#86 Patternflow-lab#87 Patternflow-lab#88 Patternflow-lab#90 Patternflow-lab#91 Patternflow-lab#89 Patternflow-lab#92
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.
dev / https://claude.ai/code/session_01UYMwmokDNM7DPd588Afarz
정리 4단계 계획서 표의 PR 17 이다. docs/midi-vectors/ 에 midi-spec.md 받는 표의 문장 하나씩을 담은 벡터 아홉 개를 두고, 시험용 RTP-MIDI 세션을 여는 _rtpmidi.ts 와 그것으로 벡터를 가상 패널에 다시 돌리는 check:midi-vectors 를 더했다. 머지되면 CI 가 PR 마다 MIDI 받는 쪽 계약을 가상 패널에 돌려 보고, 스펙 문장이 바뀌면 그 문장을 옮긴 벡터가 빨개진다.
좋아지는 것: 없음
할 일
docs/contract-vectors.md,_vectors.ts, PR 14([DONE] 정리 4단계 PR 14 — OSC 벡터 열한 개가 가상 패널에서 돌고, check:osc-vectors 가 PR 마다 본다 #80)의 OSC 스위트, PR 15([DONE] 정리 4단계 PR 15 — 가상 패널이 RTP-MIDI 세션을 받고 CC, 노트, Program Change 를 노브와 버튼, 패턴에 옮긴다 #83) 본문의 「for another k」를 읽는다web/scripts/drift/_rtpmidi.ts:rtpmidi_probe.py꼴의 이니시에이터, 벡터마다 세션 하나web/scripts/drift/midi-vectors.ts:replay("docs/midi-vectors", { midi })docs/midi-vectors/: README 와in-벡터 아홉 개heard가 읽는지 본다(k18 몫), 커밋하지 않음midi.ts로 아홉 벡터가 모두 빨개지는 것을 봤다, 되돌림. 스펙 문장 하나를 바꿔 그 벡터가 빨개지는 것도, 되돌림30e14de) 다음 PR 16([DONE] 정리 4단계 PR 16 — 가상 패널이 손으로 돌린 노브와 누른 버튼, 바뀐 패턴을 MIDI 로 보내고 /api/midi 에 답한다 #86,2ca64ac). 겹친 파일은 없고, 둘 뒤마다 typecheck, lint, check:drift, 링크, 잠금, 글투를 다시 돌렸다midi-out.ts가 들어온 패널에 버릴out벡터를 돌려heard를 포트 너머로 본다, 커밋하지 않음bb6883e에서 셋 다 success2ca64ac그대로라 merge 할 것이 없다한 일
_rtpmidi.ts는_vectors.ts에 넘기는midiSender 다. 벡터마다 UDP 소켓 둘(제어, 데이터)을 빈 포트에 열고,open()에서 패널의midi포트로 IN 을, 그다음 번호(데이터)로 같은 IN 을 보내 OK 를 받은 뒤 클럭 싱크(CK 0 → 1 → 2)를 한 번 한다. NO 가 오거나 2초 안에 답이 없으면 그 벡터는 그 까닭으로 실패한다. 걸음의midi는 채널 메시지 하나의 바이트([176, 24, 65])이고, RTP 버전 2, 페이로드 타입 97, 짧은 머리의 제 패킷에 실어 보낸다. 상태 바이트가 128~239 가 아니거나 데이터 수가 맞지 않으면 보내기 전에 던진다. 패널이 보낸 패킷은 RFC 6295 대로 읽어(짧은·긴 머리, Z 플래그, 델타 시간, 러닝 스테이터스) 메시지 하나를heard의 한 줄로 넣고, 채널 메시지가 아니면 그 바이트의 hex 를 넣어 벡터가 틀린 것이 보이게 한다.settle()은_osc.ts처럼 데이터 소켓이 자기에게 보낸 표지가 돌아올 때까지 기다린다.close()는 BY 를 보내고 소켓을 닫는다.says(midi-spec.md)in-cc-absolute0..127maps to … (rounded; 127 = 1000). (39행)params[0]0, 8, 504, 1000 · CC 21, 22, 23 이 127, 64, 1 →[1000, 1000, 504, 8], 넷 다paramActivein-cc-holdin-cc-relative64= no motion,65= +1 detent,63= −1 (40행)[1, -1, 0, 0]· 63 둘과 65 →[2, -1, 0, -2]in-cc-mergedin-cc-keeps-holdin-notes[F, F, F, T]in-program-changen(0-based, the order on/patterns). (42행)/api/patterns의active3 · PC 0 → 0in-channel0. (44행)in-ignored기다림은 20 ms 다.
docs/contract-vectors.md의 MIDI 예와 같고, PR 15 가 적은 대로 패널은 프레임 끝에 받은 것을 놓고 패턴은 다음 프레임에 받는다.in-cc-hold와in-cc-keeps-hold는 손이 250 ms 안에 쓴 채널을 되찾지 않는 펌웨어 규칙(ABSOLUTE_RELEASE_GRACE_MS)을 REST 벡터처럼 1초로 넘긴다.README 는 메시지를 적는 법,
in-/out-,/api/midi의 벡터가rest-api-vectors/midi-에 있다는 것, 세션을 스위트가 연다는 것, 20 ms 의 까닭, 스펙과 펌웨어가 다른 한 곳, 다시 돌리지 않는 것(MIDI over USB, 참가자 둘 제한, Bonjour, 재부팅 뒤 기억, 쇼, 채널 0, 63~65 밖의 상대값)을 적는다(D11).증거
로컬, web/:
처음 typecheck 는
0n같은 BigInt 리터럴에서 TS2737 로 실패했다(web 의 target 이 ES2017). 숫자로 바꿔ddbd9f6에서 고쳤다.깨뜨린 한 번:
tools/virtual-panel/transports/midi.ts를 고쳐 모든 채널을 받고, 절대값을floor(v × 1000 / 128)로 놓고 500 ms 뒤 놓고, 상대 CC 가 잡힘을 풀고 +쪽을 두 배로 하고, 벨로시티 0 노트 온을 누름으로 보고, PC 에 1 을 더하고, CC 120·121·123 에 노트를 놓게(펌웨어처럼) 했다.git checkout으로 되돌렸다.(벡터 ← 패널로 줄였다.) 스펙 문장을 바꾼 한 번:
midi-spec.md44행의 「Everything else is ignored.」를 「… is dropped.」로 바꾸면in-ignored.json: drift,says docs/midi-spec.md←says not in docs/midi-spec.md. 되돌렸다.보내는 쪽(버릴 스크립트, 커밋하지 않음). 같은 프로세스에서 패널을 띄우고 이 Sender 로 세션을 연 뒤, 패널의
midi(sim).send()와 다른 소켓에서 지어 보낸 패킷을heard가 어떻게 읽는지 봤다:PR 16 을 merge 한 뒤, 같은 Sender 로
out을 보는 버릴 벡터 하나를replay()에 돌렸다(폴더째 지웠다). 손 K1 +1 →[176, 24, 65],/api/patterns/select?index=2→[192, 2], 호스트의 CC 25 = 65 → 100 ms 동안<absent>, status 의midi.rtpPeers1 과rtpPeer"check:midi-vectors" 가 맞았다. 버튼 둘은 내가 채널 3 상태 바이트(146, 130)를 잘못 적어 drift 였고, 패널이 보낸 것은[144, 62, 127] at 50 ms,[128, 62, 0] at 50 ms로 채널 1 그대로였다.heard가 패널이 보낸 것을 그 시각과 함께 보여 준다는 증거로 둔다.dev 의 PR 20 과 PR 16 을 merge 한
bb6883e에서 다시:GitHub, 이 PR:
bb6883e에서 「Drift checks / check」(116538099274), 「Docs point at files that exist / check」(116538083143), 「Web CI / build」(116538104103) 셋 다 success. PR 16 merge 전5e8dee5에서도 셋 다 success 였다(116533549112, 116533553251, 116533928042).doc-map 의 새 줄은 다섯이고 다 닿는다.
docs/midi-vectors/README.md에서docs/midi-spec.md,docs/contract-vectors.md,docs/rest-api-vectors/README.md,tools/virtual-panel/README.md,tools/rtpmidi-probe/rtpmidi_probe.py로.실행법
벡터 하나를 고쳐 보려면
docs/midi-vectors/의 JSON 을 고치고 같은 명령을 돌린다. git 에 넣기 전에도 디스크에서 읽는다.가정
docs/midi-vectors/README.md,docs/midi-vectors/in-*.json,_rtpmidi.ts,midi-vectors.ts만 더했다.CHANGELOG.md,docs/rfc-cleanup-progress.md, doc-map CSV,web/package.json(PR 2 가check:midi-vectors를 이미 넣었다),midi.ts는 안 고쳤다. 라벨은 앞 PR 들처럼 달지 않았다.out-과rest-api-vectors/midi-까지 적었다. 표가 README 를 k17 에만 주어 k18 은 고칠 수 없기 때문이다.isMessage를 넓힌다.rtpmidi_probe.py가 하고, 기기는 참가자를 둘까지만 받아 남겨 두지 않는다. 실제 기기를 걷는 일은 이 단계가 아니다(질문 29).in-program-change,in-channel,in-ignored는 새 패널이 Origin(번호 0)에서 시작한다고 본다. 패널의 시작 상태다.firmware/와web/src/를 건드리지 않아build.sh all,check:ci,check:panels는 §2.1(1) 대상이 아니다. 계획서대로 typecheck 와 이 PR 의 check, 깨뜨린 한 번을 적었다.Changelog
Tools
docs/midi-vectors/holds nine, each one sentence of the host → device table indocs/midi-spec.mdand the messages that show a panel doing it, from CC 20 at 127 landing on 1000 to a message on channel 2 the panel ignores.npm run check:midi-vectorsinweb/replays them against the virtual panel built with themidifeature, over an RTP-MIDI sessionweb/scripts/drift/_rtpmidi.tsopens for each, and CI runs it with the other drift checks.for an issue
D9. 벡터는 스펙을 따르고, 펌웨어는 한 곳에서 다르다(PR 15 의 「k17, for an issue」와 같다).
in-ignored.json·midi-spec.md44, "Everything else is ignored." ·core_midi.h:296이 CC 120, 121, 123 에 누르던 노트를 모두 놓는다(clearNotes()). 노트 60 을 누른 채 CC 123 을 보내면 기기에선 held 가 풀린다.for another k
import { midi } from "./_rtpmidi".heard는 패널이 보낸 채널 메시지를[status, ...data]로, 러닝 스테이터스를 채워 한 줄씩 담는다. 채널 메시지가 아니면 hex 글이다. 세션은 첫 걸음 전에 열리므로midi-out.ts가 보내는 것이 처음부터 닿는다(위 버릴out벡터, 시각까지). README 는out-과rest-api-vectors/midi-를 이미 적었다.check:rest-vectors는midiSender 를 가져오지 않아rest-api-vectors/midi-*.json은http,hand,wait만 쓸 수 있다. 세션이 있어야 보이는 것(rtpPeers,rtpPeer,rx)은docs/midi-vectors/out-*.json에 두어야check:midi-vectors가 세션을 열고 돌린다.docs/README.md의midi-spec.md줄에midi-vectors/를, pfst 줄처럼.midi-spec.md40행이 CC 24~27 을 「two's-complement offset」이라 하고, 제 예와 57행은 binary offset 이다. 패널과 펌웨어(core_midi.h:287)는 값 − 64 로 읽는다. 벡터는 둘이 맞는 63, 64, 65 만 보낸다.Upstream
npm run typecheck,npm run lintandnpm run check:drift(midi-vectors included) pass; firmware/ and web/src/ are untouched.🤖 Generated with Claude Code
https://claude.ai/code/session_01UYMwmokDNM7DPd588Afarz