Skip to content

Assess what wiring A-12 actually requires - #96

Open
heijiLee wants to merge 1 commit into
mainfrom
docs/a-12-wiring-assessment
Open

Assess what wiring A-12 actually requires#96
heijiLee wants to merge 1 commit into
mainfrom
docs/a-12-wiring-assessment

Conversation

@heijiLee

@heijiLee heijiLee commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

"컨트랙트는 이미 있으니 목록에 한 줄 추가하고 재배포"라는 진단을 검증한 결과다. 코드 변경은 없다.

전체 스택 재배포가 필요 없다는 부분은 맞다. 이 시스템은 registry 트랜잭션 모델이다. 하지만 실제 작업은 그보다 크다.

실제로 필요한 것

  • Recipe의 element 목록은 생성자 데이터로 불변이다 (BaseRecipe_elements를 들고 있고 setter가 없다). 따라서 RegD506cRecipe를 고치는 게 아니라 새 (recipeId, version)으로 새 Recipe 컨트랙트를 배포해야 한다.
  • ElementRegistry 등록은 elementId당 1회이고 ElementAlreadyRegistered로 revert한다. 즉 최초 등록 시 고른 default enforcement action이 영구적이다.
  • 영향받는 자산마다 scheduleManifestUpdate → 1일 timelock → activateManifestUpdate가 필요하다. binding은 갱신 시점에 컴파일되며 거래 시점에 조회되지 않는다.
  • 온보딩 번들 항목은 id 문자열이 아니다. element는 배포된 implementation 주소, defaultAction, versionHash를 갖고, recipe의 requiredElements와 교차 검증된다.

먼저 잡아야 할 함정

wave-3 배포 스크립트(tools/deploy-wave3/DeployWave3Elements.s.sol:40)는 A-12를 2-인자 registerElement 오버로드로 등록하는데, 이 오버로드는 EnforcementAction.BLOCK을 하드코딩한다. 반면 A-12는 설계상 절대 gate하지 않으며 check()가 항상 true를 반환한다.

등록이 불가역이고 FORCE_FLAG_ONLY는 이미 FLAG_ONLY가 기본인 element에만 허용되므로(TokenPolicyRegistry.sol:505-507, LooseningForbidden), 이 스크립트를 지금 그대로 실행하면 "A-12-v1"이 잘못된 기본값에 영구히 묶인다. 나중에 override로도 못 고친다. 오늘 사고가 안 나는 이유는 check()가 항상 통과하기 때문뿐이다.

차단 요인은 엔지니어링만이 아니다

ADR-010 §10이 A-12를 리걸 사유로 별도 논의 대상으로 미뤄두었다. 게다가 정의가 아직 안 맞는다: 구현된 A-12는 mark-only(비-게이팅)인데, ADR-010 §10의 법적 논거는 게이팅 메커니즘을 요구한다.

권고: 이번 데모에서는 A-12를 배선하지 않는다. 이 질문이 정리되기 전에 배선하면 배선 자체를 다시 바꿔야 할 수 있다.

별건으로 발견한 문서 불일치

docs/compliance/spec-sheets/A-12_willful-blindness.spec.md:15는 여전히 A-12를 "전용 컨트랙트가 아직 구현되지 아니한 법률 전용(legal-only) 부품"으로 기술한다. 그러나 RedFlagKnowledgeBar.sol은 2026-07-22부터 존재한다. 리걸 쪽이 컨트랙트가 만들어진 걸 모르고 있을 수 있다. 이 PR에서 고치지는 않았고 문서에만 적어두었다.

검증

docs 전용이라 build/test 영향 없음.

"The contract exists, so add one line to the bundle list and redeploy" is not
accurate. No full-stack redeploy is needed, that part of the assumption is
right: this is a registry-transaction model. But the real work is larger.

- Recipe element lists are immutable constructor data (`BaseRecipe` stores
  `_elements` with no setter), so adding A-12 means deploying a new Recipe
  contract under a new (recipeId, version), not editing `RegD506cRecipe`.
- `ElementRegistry` registration is one-shot per elementId and reverts
  `ElementAlreadyRegistered`, so the default enforcement action chosen at first
  registration is permanent.
- Each affected asset needs `scheduleManifestUpdate`, a 1 day timelock, then
  `activateManifestUpdate`. Bindings are compiled at update time, not resolved
  at trade time.
- The onboarding bundle entry is not an id string: elements carry a deployed
  implementation address, defaultAction and versionHash, cross-validated
  against the recipe's `requiredElements`.

Records one trap worth catching before anyone acts: the wave-3 deploy script
registers A-12 through the 2 argument `registerElement` overload, which
hardcodes `EnforcementAction.BLOCK`, while A-12 is designed never to gate and
its `check()` always returns true. Because registration is irreversible and
`FORCE_FLAG_ONLY` is legal only for elements already defaulting to FLAG_ONLY,
running that script as-is would permanently bind "A-12-v1" to a wrong default.

The blocker is not only engineering. ADR-010 section 10 defers A-12 for legal
reasons, and the implemented element is mark-only while that legal argument
calls for a gating mechanism. Recommend not wiring A-12 for the demo until
that is settled.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant