에이전트에게 파일을 쓰게 하려면 컴퓨터의 경로부터 알려 줘야 할까. 북극성에서는 사람이 선택한 자료를 핸들로 등록하고 이번 작업에 허용한 ID만 연결했다. 자료를 찾는 편의와 다른 작업의 파일까지 읽게 되는 권한을 함께 묶지 않으려는 선택이었다.
등록한 파일 전체와 이번에 고른 파일은 다르다
TaskFiles.add는 실제 파일을 검사한 뒤 이름과 크기, 경로와 수정 시각을 내부에 기억한다. 반환값은 이번에 입력한 파일들의 ID다. 예전에 등록해 둔 다른 자료까지 반환하는 목록과 구별했다. 한 번 올렸던 사진이 등록돼 있다는 이유로 다음 글의 첨부 목록에 자동으로 섞이면 안 되기 때문이다.
같은 프로필에서 경로·크기·수정 시각이 같은 파일은 기존 핸들을 재사용한다. 같은 파일을 반복해서 요청해도 서로 다른 선택 스무 개처럼 쌓지 않는다. 반면 다른 프로필은 같은 경로여도 별도 핸들을 받는다. 경로 비교의 Windows 대소문자 규칙까지 고려하지만 이것을 내용의 완전한 동일성 판정이라고 부르지는 않는다.
스무 개 제한은 중간 등록을 남기지 않게 했다
add는 새 항목을 pending에 모은 다음 프로필의 기존 항목과 합쳐 한도를 확인한다. 서로 다른 스물한 개가 들어와 제한을 넘으면 그 요청의 앞부분만 등록해 두지 않는다. 호출자가 실패를 받았는데 내부에는 열아홉 개가 남아 있는 식의 불일치를 줄이는 구조다.
기존 자료를 재사용하는 요청은 pending을 늘리지 않는다. 선택 결과의 중복 ID도 정리해서 돌려준다. 내가 중요하게 본 것은 숫자 자체보다 실패 전후의 설명 가능성이었다. 제한 때문에 거절했으면 어떤 새 선택도 확정되지 않아야 다음 요청이 왜 다시 가능한지 판단하기 쉽다. 파일을 디스크에서 지우는 동작은 이 등록 절차에 없다.
ID를 알고 있어도 작업 허용 목록을 다시 본다
describe와 upload는 프로필만 확인하지 않는다. 요청한 ID가 현재 작업의 allowed 목록에 있는지도 검사한다. task-controller는 실행 범위의 files에서 그 목록을 만든다. TaskFiles 자체가 project 인자를 직접 받아 모든 프로젝트 권한을 해결하는 구조라고 설명하면 실제 코드와 어긋난다.
describe는 읽기 전과 해시를 계산한 뒤에 파일의 종류·크기·수정 시각을 검사한다. 도중에도 작업 취소 검사를 한다. 반환값에는 ID·이름·크기·SHA256만 있고 실제 경로는 없다. 경로를 덜 공개하는 것과 읽기 권한 검사는 서로 보완하지만, 경로를 숨겼다는 이유만으로 권한 검사를 생략할 수는 없다.
업로드 직전에도 선택 수명이 끝나지 않았는지 본다
파일 선택은 처음 검사한 순간에서 끝나지 않는다. upload는 드라이버에 넘기기 전에 현재 메타데이터를 확인하고, 실제 dispatch 직전 콜백에서도 핸들이 같은 등록 항목인지와 파일 상태를 다시 검사한다. 선택을 철회했거나 내용이 달라진 자료를 옛 ID로 계속 보내려는 상황을 멈추기 위한 위치다.
드라이버가 돌려준 이름·크기 목록은 예상 목록과 정확히 비교한다. 이 비교가 통과한 verified에는 파일 선택 확인이며 서버 전송 완료는 페이지 결과로 보라는 설명이 붙는다. 같은 이름이 보이는 것, 서버가 첨부를 수신한 것, 글에 반영된 것은 각각 다른 증거다. 뒤의 확인이 없으면 앞 단계의 성공을 확대하지 않는다.
공유 예제는 더 작은 권한 실험으로 남겼다
공개한 합성 모듈은 실제 경로 대신 직접 전달한 bytes를 저장한다. profile과 project를 명시한 작은 Scope, 허용 ID, 선택 철회와 동일 크기 내용 변경을 시험할 수 있다. 원래 프로필 기반 등록과 작업 허용 목록을 이해하기 위한 독립 모델이지 운영 파일 선택창의 복제는 아니다.
원본 단위시험에서 반복 등록의 재사용과 제한 초과의 원자적 거절, 변경 파일의 업로드 거절을 읽었다. 이 글을 위해 원래 브라우저를 새로 실행한 것은 아니다. 합성 예제는 별도 로컬 시험과 ZIP 추출 시험으로 확인했다. 재사용하는 사람이 어느 검사가 실제 바이트를 보고 어느 검사가 호출자의 선언을 받는지 알 수 있게 범위를 남겼다.