refactor: 문서 개선 중

This commit is contained in:
donghyeon-ka
2026-09-21 14:30:55 +09:00
parent c93cdea150
commit 805a18f486
1497 changed files with 525837 additions and 59152 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,23 +1,23 @@
{
"version": "1.1",
"id": "redis-admission-stages",
"title": "명령 입장의 단일 지점",
"question": "명령은 어디서 걸러지는가?",
"type": "dependency",
"title": "의도된 guarded path와 실제 direct gateway 우회",
"question": "Redis 명령은 guard를 통과하는가, semantic adapter에서 gateway로 우회하는가?",
"type": "flow",
"direction": "LR",
"audience": [
"이 저장소의 구조를 읽는 사람"
"백엔드 엔지니어"
],
"summary": "카탈로그를 통과하면 실행이고 미분류나 BLOCKED 이면 fail-closed 로 거절된다.",
"alt": "CommandPolicyGuard 에서 카탈로그 통과는 실행으로 미분류와 BLOCKED 는 거절로 갈린다.",
"long_description": "SSOT 는 이 구조의 바닥이 카탈로그가 미분류 명령을 fail-closed 로 거부하는 것이라고 적는다.",
"summary": "guarded command path에서는 CommandPolicyGuard가 admission을 담당하지만, 현재 semantic adapter 다섯은 gateway를 직접 호출해 이 경로를 우회한다.",
"alt": "의도된 command path는 CommandPolicyGuard를 거쳐 실행 또는 fail-closed 거절로 갈리고, 별도의 semantic adapter 경로는 RedisCommandGateway를 직접 호출해 guard를 우회하는 흐름도",
"long_description": "CommandPolicyGuard는 guarded command path의 admission 지점이다. 그러나 현재 semantic adapter 다섯은 RedisLease에서 gateway를 직접 얻어 호출하므로 catalog, permit, slot, budget, translation, observation 단계가 이 경로에 적용되지 않는다.",
"source_context": {
"document": "/home/donghyeon/workspace/chat-gpt-container/document-haness/docs/clean-architecture-backend-template/final/document.md",
"document_sha256": "8071fe71b3359d9cf60b95909c26c7b50653ce2f22bbc5fcf6988719bb91236d",
"document": "docs/clean-architecture-backend-template/final/document.md",
"document_sha256": "7c986b30b6ef3c12060b6749ee60d53e37d6994493d2703419732c9cab6077d8",
"anchor": {
"kind": "line",
"value": 13463,
"line": 13463
"value": 13469,
"line": 13469
}
},
"composition": {
@@ -26,20 +26,33 @@
"reference_ids": [
"payment-event-flow"
],
"rationale": "한 지점이 모든 명령을 두 결과로 가른다는 것이 논지다.",
"focus_node": "guard"
"rationale": "의도된 guarded path와 실제 bypass path를 한 화면에서 대비해야 전체 runtime의 single admission으로 오해하지 않는다.",
"focus_node": "bypass"
},
"groups": [],
"nodes": [
{
"id": "guard",
"label": "CommandPolicyGuard",
"id": "typed-entry",
"label": "guarded command path",
"kind": "service",
"role": "source",
"evidence": [
{
"start_line": 13463,
"end_line": 13490
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false
},
{
"id": "guard",
"label": "CommandPolicyGuard",
"kind": "service",
"role": "service",
"evidence": [
{
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false,
@@ -47,69 +60,150 @@
},
{
"id": "run",
"label": "실행",
"kind": "service",
"label": "승인 후 실행",
"kind": "result",
"role": "sink",
"evidence": [
{
"start_line": 13463,
"end_line": 13490
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false,
"details": [
"카탈로그 통과"
]
"assumption": false
},
{
"id": "deny",
"label": "fail-closed 거절",
"kind": "result",
"role": "sink",
"evidence": [
{
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false
},
{
"id": "semantic",
"label": "semantic adapters ×5",
"kind": "service",
"role": "source",
"evidence": [
{
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false
},
{
"id": "gateway",
"label": "RedisCommandGateway 직접 호출",
"kind": "service",
"role": "sink",
"evidence": [
{
"start_line": 13463,
"end_line": 13497
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false
},
{
"id": "bypass",
"label": "guard stages 우회",
"kind": "result",
"role": "sink",
"evidence": [
{
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false,
"emphasis": "primary",
"details": [
"미분류 · BLOCKED"
"catalog · permit · slot · budget",
"translation · observation"
]
}
],
"edges": [
{
"id": "a",
"id": "entry",
"from": "typed-entry",
"to": "guard",
"label": "admission",
"kind": "request",
"evidence": [
{
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false
},
{
"id": "pass",
"from": "guard",
"to": "run",
"label": "통과",
"kind": "request",
"kind": "data",
"evidence": [
{
"start_line": 13463,
"end_line": 13490
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false,
"emphasis": "primary"
"assumption": false
},
{
"id": "b",
"id": "reject",
"from": "guard",
"to": "deny",
"label": "거절",
"kind": "data",
"evidence": [
{
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false
},
{
"id": "direct",
"from": "semantic",
"to": "gateway",
"label": "lease.gateway()",
"kind": "request",
"evidence": [
{
"start_line": 13463,
"end_line": 13497
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false,
"style": "dashed"
},
{
"id": "skips",
"from": "gateway",
"to": "bypass",
"label": "guard 미경유",
"kind": "data",
"evidence": [
{
"start_line": 13469,
"end_line": 13503
}
],
"assumption": false,
"style": "dashed",
"emphasis": "primary"
}
],
"legend": [],
"metadata": {}
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,140 +1,146 @@
{
"version": "1.1",
"id": "rls-three-preconditions",
"title": "격리가 성립하는 세 조건",
"question": "RLS 격리는 무엇이 동시에 참이어야 성립하는가?",
"type": "sequence",
"direction": "LR",
"title": "PostgreSQL RLS 적용 여부를 가르는 분기",
"question": "현재 role과 table에서 RLS policy가 실제로 적용되는가?",
"type": "data-flow",
"direction": "TB",
"audience": [
"이 저장소의 구조를 읽는 사람"
"백엔드 엔지니어"
],
"summary": "ENABLE RLS 와 FORCE RLS 와 BYPASSRLS 없는 런타임 롤 셋이 동시에 참이어야 격리가 성립한다.",
"alt": "격리 판정이 ENABLE RLS 와 FORCE RLS 와 BYPASSRLS 없는 롤을 차례로 확인하는 순서.",
"long_description": "SSOT 는 RlsPolicyVerifier.requireEnforced 가 런타임 롤의 BYPASSRLS 를 확인하고 current_schema() 의 실제 테이블을 순회하며 tenant-scoped 목록에 든 것만 검사한다고 적는다.",
"summary": "RLS 활성 여부, 우회 role, owner와 FORCE RLS, applicable policy 유무를 차례로 구분한다.",
"alt": "RLS 비활성은 policy 미적용으로, superuser와 BYPASSRLS는 우회로, owner는 FORCE 여부로 갈리고, policy 대상인데 applicable policy가 없으면 default deny가 되는 흐름도",
"long_description": "PostgreSQL RLS를 세 개의 동시 전제로 보지 않는다. RLS가 활성화된 뒤 superuser 또는 BYPASSRLS인지, table owner인지와 FORCE RLS 여부를 확인한다. policy 대상 role에 applicable policy가 없으면 default deny이고, policy가 있으면 USING과 WITH CHECK를 평가한다.",
"source_context": {
"document": "/home/donghyeon/workspace/chat-gpt-container/document-haness/docs/clean-architecture-backend-template/final/document.md",
"document_sha256": "8071fe71b3359d9cf60b95909c26c7b50653ce2f22bbc5fcf6988719bb91236d",
"document": "docs/clean-architecture-backend-template/final/document.md",
"document_sha256": "7c986b30b6ef3c12060b6749ee60d53e37d6994493d2703419732c9cab6077d8",
"anchor": {
"kind": "line",
"value": 7398,
"line": 7398
"value": 7400,
"line": 7400
}
},
"composition": {
"profile": "sequence",
"profile": "two-zone-pipeline",
"diagram_only": true,
"reference_ids": [
"payment-approval-sequence"
"localization-pipeline"
],
"rationale": "세 조건이 차례로 확인되어야 격리가 성립한다는 순서가 논지다.",
"focus_node": "verifier"
"rationale": "정책 적용 여부를 결정하는 검사 경로와 각 단계에서 빠져나가는 결과를 짧은 파이프라인으로 보여 준다.",
"focus_node": "policy"
},
"groups": [],
"nodes": [
"groups": [
{
"id": "start",
"label": "격리 판정",
"kind": "service",
"role": "participant",
"id": "role",
"label": "policy 적용 대상 판정",
"evidence": [
{
"start_line": 7396,
"end_line": 7420
"start_line": 7400,
"end_line": 7432
}
],
"assumption": false
},
{
"id": "verifier",
"label": "RlsPolicyVerifier",
"kind": "service",
"role": "participant",
"id": "policy-zone",
"label": "policy 존재와 평가",
"evidence": [
{
"start_line": 7396,
"end_line": 7420
"start_line": 7400,
"end_line": 7432
}
],
"assumption": false
}
],
"nodes": [
{
"id": "rls",
"label": "RLS 활성 여부",
"kind": "process",
"role": "stage",
"evidence": [
{
"start_line": 7400,
"end_line": 7432
}
],
"assumption": false,
"emphasis": "primary"
"group": "role",
"details": [
"no → policy 미적용"
]
},
{
"id": "db",
"label": "데이터베이스",
"kind": "database",
"role": "participant",
"id": "subject",
"label": "policy 적용 대상",
"kind": "process",
"role": "stage",
"evidence": [
{
"start_line": 7396,
"end_line": 7426
"start_line": 7400,
"end_line": 7432
}
],
"assumption": false
"assumption": false,
"group": "role",
"details": [
"superuser / BYPASSRLS → 우회",
"owner + FORCE off → 우회",
"non-owner 또는 owner + FORCE on → 대상"
]
},
{
"id": "policy",
"label": "applicable policy",
"kind": "process",
"role": "stage",
"evidence": [
{
"start_line": 7400,
"end_line": 7432
}
],
"assumption": false,
"group": "policy-zone",
"emphasis": "primary",
"details": [
"none → default deny",
"exists → USING / WITH CHECK 평가"
]
}
],
"edges": [
{
"id": "m1",
"from": "start",
"to": "verifier",
"label": "검증 요청",
"id": "e1",
"from": "rls",
"to": "subject",
"label": "RLS on",
"kind": "request",
"evidence": [
{
"start_line": 7396,
"end_line": 7420
"start_line": 7400,
"end_line": 7432
}
],
"assumption": false,
"order": 1
"assumption": false
},
{
"id": "m2",
"from": "verifier",
"to": "db",
"label": "ENABLE RLS 확인",
"id": "e2",
"from": "subject",
"to": "policy",
"label": "적용",
"kind": "request",
"evidence": [
{
"start_line": 7396,
"end_line": 7420
"start_line": 7400,
"end_line": 7432
}
],
"assumption": false,
"order": 2
},
{
"id": "m3",
"from": "verifier",
"to": "db",
"label": "FORCE RLS 확인",
"kind": "request",
"evidence": [
{
"start_line": 7396,
"end_line": 7420
}
],
"assumption": false,
"order": 3
},
{
"id": "m4",
"from": "verifier",
"to": "db",
"label": "BYPASSRLS 없음 확인",
"kind": "request",
"evidence": [
{
"start_line": 7396,
"end_line": 7426
}
],
"assumption": false,
"order": 4,
"emphasis": "primary"
}
],
"legend": [],
"metadata": {}
}
}