P02 지점 운영자 자기 프로필 실제 actor acceptance
이 페이지는 P02-branch-manager-profile의 canonical 실제 actor 근거다. Phase ID의
branch-manager는 호환 이름이고 canonical role은 branch_operator다. 증거 판정은
phaseAcceptancePassed: true, 전체 마이그레이션 판정은 completionClaim: false다.
P03부터 P13까지 통과하기 전에는 100% 완료를 주장하지 않는다.
상위 결정 권위는 ADR-030과 ADR-033이다. 구현 전에 고정한 문턱은 P02 workflow-first RED 역사 기록에 보존한다.
고정 composition
Section titled “고정 composition”| Role | Revision | Tree |
|---|---|---|
| assembly | 69038b47f97b68d5e3b7a7ec9fa223032bc2d8cf | ef101e421753387cc65ee1683a628d40857a865e |
| contract | f2457fb12e08991881d4a41ce86233fe33f59c49 | 1df3214e49d2ae4b5d73c33b5d6875428d4c3d56 |
| backend | ba4fe75cf4a126f9f1eccf2370dddd8651c96ca8 | 7580b45cc12e737edb32b0a7e8959eacd6e2464b |
| frontend | 8440ef6480d7b801ec92e4b2575e8f75a49e493c | 2d1396887512012ec1f8d2ce6970735b58c4625b |
브라우저가 사용한 frontend artifact는
sha256:ff97596dd05b45b08134199153bd7c71616ed0e8ffee45a7ec3f88c3d351ef9b, backend
container image는
sha256:47965cdc9d53a515f68f78241161c901e70051ce428f12e791bd7fe19f6a631a다.
canonical-pack.json은 API network assertion과 Supabase primary-state actor proof를 각 source
hash에 묶은 통합 canonical pack이다. 이름을 맞추기 위한 별도 가짜 manifest를 만들지 않는다.
레거시 기준과 현대화 경계
Section titled “레거시 기준과 현대화 경계”| Anchor | 레거시 실제 동작 | 검증한 경계 |
|---|---|---|
source-refs/sanmopia-admin/application/controllers/OfficeManagement.php:374-381 | non-admin 상세 GET만 URL index를 session 지점으로 치환한다. | GET과 PATCH 모두 server-resolved subject와 정확히 하나의 active membership을 사용한다. |
source-refs/sanmopia-admin/application/controllers/OfficeManagement.php:399-448 | 상세 POST는 caller $index를 저장 경계에 그대로 넘긴다. | public own-profile 입력에는 branch/profile/actor id가 없다. |
source-refs/sanmopia-admin/static/js/office_management/office_detail.js:1-10 | 일부 input을 readonly로 표시한다. | UI 표시가 아니라 backend authority와 closed request schema가 권한을 강제한다. |
source-refs/sanmopia-admin/static/js/office_management/office_detail.js:253-276 | caller index로 POST한 뒤 reload/history 이동을 섞는다. | full projection, revision, exact replay, stale conflict recovery를 명시한다. |
source-refs/sanmopia-admin/application/models/Branch_model.php:202-286 | profile, credential, lifecycle, 계좌, 회비를 한 호출에서 갱신한다. | P02 PATCH는 표시·연락·구조화 주소 facts만 변경한다. |
A→Z 실제 검증 절차
Section titled “A→Z 실제 검증 절차”-
A — immutable 입력 고정
assembly, contract, backend, frontend의 clean revision과 tree를 기록한다.
-
B — runtime artifact 고정
실제 backend container image/source tree와 production frontend artifact digest를 기록한다.
-
C — P01 prerequisite 생성
실제 HQ actor가 test-owned branch, invited operator authority, onboarding 최소 profile을 만들고 accepted P01 lineage
1을 따로 추적한다. -
D — 실제 Supabase session
invited
branch_operator의 실제 Auth session을 발급한다. token, cookie, email, UUID는 게시 근거에 남기지 않는다. -
E — activation context 거부
anonymous context는
401, 다른 actor context는 scope-safe403|404이며 primary mutation은0인지 확인한다. -
F — activation ready
self-scoped context가 server revision,
invitationStatus: sent,activationReadiness: ready를 반환하는지 확인한다. -
G — 가짜 사전 권한 차단
P01 SpiceDB
manage가 미리 존재해도 activation 전 profile GET/PATCH가403, command mutation이0인지 확인한다. -
H — invitation activation
caller scope id 없이 activation을 실행해 HTTP
201과authorizationRelationshipStatus: pending을 확인한다. -
I — activation 원자성
invitation accepted, membership active, activation audit, relationship delivery intent가 exact lineage에서 한 번만 전진하는지 Supabase primary snapshot으로 대조한다.
-
J — accepted context
같은 context가
invitationStatus: accepted,activationReadiness: already_accepted로 전이됐는지 확인한다. -
K — activation exact replay
같은 actor/key/payload의 HTTP
200replay 전후 membership, member profile, invitation, audit, live/archive queue cardinality와 canonical state가 같은지 확인한다. -
L — pending delivery 거부
worker 적용 전 profile GET/PATCH는 모두
403, profile command와 primary mutation은0인지 확인한다. -
M — 경쟁 worker 격리
기존 worker 상태를 먼저 판정하고 runner가 실행 중 worker만 일시 정지한다. 캡처 종료 뒤 원래 상태를 복구하며 이 격리가 실패하면 증거를 만들지 않는다.
-
N — relationship delivery
runner가 소유한 worker가 exact queue intent를 archive하고 application receipt를 남기는지 확인한다.
-
O — SpiceDB 권한 검증
canonical
branch_operatorrelationship과managepermission이 실제 SpiceDB에 수렴한 뒤에만 profile route를 연다. -
P — 자기 profile GET
branch id 없는
GET /branch/profileHTTP200, full operator-visible projection, revision, completeness,allowedNextActions를 확인한다. -
Q — authorized PATCH
표시명, 연락 이메일, E.164 전화번호, 구조화 주소, reason, expected revision만 보내 HTTP
201과 revision 1회 증가를 확인한다. -
R — primary/non-owner authority 대조
current profile, revision, command result는 public projection과 같고 legal/business/lifecycle, fee, account, service-area, credential facts는 canonical byte-equivalent로 불변인지 확인한다.
-
S — profile exact replay
같은 actor/key/payload가 HTTP
200, 같은 projection,idempotentReplay: true를 반환하고 추가 revision/audit mutation은0인지 확인한다. -
T — conflict 2 variants
same-key different-payload와 stale revision
409 latestProjection/fieldDiff가 모두 accepted authority를 바꾸지 않는지 확인한다. -
U — validation 6 variants
email, phone, postal address, blank reason, unknown field, HQ-only legal name 오류를 closed
422로 거부하고 부분 저장0을 확인한다. -
V — authorization 13 variants
context actor, pre-activation, pending delivery, foreign/HQ actor, generic bypass, 복수 active membership, withdrawn identity의 GET/PATCH를
401|403|404로 닫고 mutation0을 확인한다. -
W — desktop 실제 browser
1440px production build에서 activation, edit, apply, exact replay, stale conflict recovery와 실제 API network를 확인한다.
-
X — mobile 실제 browser와 WebP
390px activation/replay/stale recovery에 horizontal overflow가 없음을 확인하고 서로 다른 실제 상태 여섯 frame을 animated WebP로 고정한다.
-
Y — cleanup과 process residue
operational/Auth/relationship residue를 각각
0으로 만들고 Chromium/profile/frontend process residue도0인지 확인한다. activation audit·application receipt·P01 lineage만 정해진 cardinality로 보존한다. -
Z — privacy와 범위 판정
token, key, body, PII, opaque identifier, private topology가 없고 다섯 PNG와 여섯-frame WebP가 redaction review를 통과했을 때 P02만 PASS로 판정한다.
여섯 acceptance case
Section titled “여섯 acceptance case”| Case | 실제 proof |
|---|---|
P02-happy-path | context ready/accepted, activation 201, pending 403, worker receipt, GET 200, PATCH 201 |
P02-authorization | closed authorization 13 variants, mutation 0 |
P02-validation | closed validation 6 variants, 모두 422, mutation 0 |
P02-conflict | conflicting replay와 stale revision 2 variants, accepted authority 불변 |
P02-exact-replay | activation/profile replay 200, canonical state·projection 동일, 중복 mutation 0 |
P02-cleanup | actor/browser operational·Auth·relationship 0, process residue 0, retained cardinality 일치 |
실제 UI 근거
Section titled “실제 UI 근거”





브라우저 manifest는 route interception과 mock network가 모두 false, 예상 밖 console error와
failed request가 0, mobile document overflow가 없음을 기록한다. competing worker는 runner가
일시 정지하고 원래 running 상태로 복구했다.
Cleanup·privacy 권위
Section titled “Cleanup·privacy 권위”| 상태 | Actor run | Browser run |
|---|---|---|
| test-owned operational residue | 0 | 0 |
| temporary Auth identity | 0 | 0 |
| temporary SpiceDB relationship | 0 | 0 |
| retained activation audit | 1 | 1 |
| retained application receipts | 2 | 2 |
| retained accepted P01 lineage | 1 | 1 |
Canonical machine evidence는 docs/evidence/p02-branch-operator-profile/의 actor run, browser run,
combined canonical pack, cleanup manifest, privacy review가 소유한다. access/refresh token, cookie,
idempotency key, request/response body, actor/resource identifier, PII, private topology는 보존하지
않았다.