From 6c53ded9cb70f2d7cf3e66ff50d42f2d151c98b1 Mon Sep 17 00:00:00 2001 From: DongHyeonka Date: Fri, 24 Jul 2026 14:21:35 +0900 Subject: [PATCH] =?UTF-8?q?init:=20llm-wiki-haness=20=ED=95=98=EB=84=A4?= =?UTF-8?q?=EC=8A=A4=20=EC=84=A4=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 137 + CLAUDE.md | 409 + README.md | 131 +- cspell.json | 103 + docs/superpowers/README.md | 95 + ...026-06-04-phase1-empirical-format-check.md | 57 + ...-06-04-phase2-antigravity-hook-coverage.md | 39 + .../2026-06-04-phase2-codex-hook-schema.md | 29 + .../plans/2026-06-01-branch-depth-gate.md | 385 + ...6-02-obsidian-link-validation-hardening.md | 426 + ...hree-platform-sync-phase0-engine-agents.md | 809 ++ ...-04-three-platform-sync-phase1-commands.md | 470 + ...ree-platform-sync-phase2-hooks-agentsmd.md | 298 + ...wiki-project-template-source-type-split.md | 405 + .../2026-06-05-investment-wiki-pipeline.md | 1005 ++ .../plans/2026-06-05-project-note-pipeline.md | 746 ++ ...6-06-spec-a-deterministic-backbone-gate.md | 682 ++ ...-spec-b-judge-verdict-schema-and-quorum.md | 621 ++ ...pec-c-funnel-stats-no-silent-truncation.md | 354 + ...6-06-06-spec-d-research-fanout-workflow.md | 218 + .../plans/2026-06-08-invest-field-map.md | 1023 ++ .../2026-06-08-invest-system-buildout.md | 241 + ...09-deep-research-codex-antigravity-port.md | 1483 +++ .../2026-07-14-harness-correctness-sweep.md | 451 + .../2026-06-01-branch-depth-gate-design.md | 159 + ...ability-foundation-reinforcement-design.md | 83 + .../2026-06-01-wiki-structure-lint-design.md | 107 + ...02-branch-spec-assembly-pipeline-design.md | 84 + .../specs/2026-06-02-coverage-gate-design.md | 136 + .../2026-06-02-korean-prose-style-design.md | 55 + ...sidian-link-validation-hardening-design.md | 97 + ...6-06-02-validation-strengthening-design.md | 43 + ...-ca-tmpl-optimization-per-file-findings.md | 581 ++ .../2026-06-04-ca-tmpl-optimization-report.md | 279 + ...-04-three-platform-workflow-sync-design.md | 160 + ...oject-template-source-type-split-design.md | 159 + ...6-06-05-investment-wiki-pipeline-design.md | 205 + ...2026-06-05-project-note-pipeline-design.md | 166 + .../specs/2026-06-06-harness-audit-report.md | 175 + ...ec-a-deterministic-backbone-gate-design.md | 146 + ...-judge-verdict-schema-and-quorum-design.md | 263 + ...unnel-stats-no-silent-truncation-design.md | 168 + ...-spec-d-research-fanout-workflow-design.md | 168 + .../2026-06-08-invest-field-map-design.md | 172 + ...-08-spec-e-antigravity-hook-port-design.md | 85 + ...spec-f-invest-pipeline-hardening-design.md | 62 + ...-research-codex-antigravity-port-design.md | 271 + .../2026-06-10-claude-harness-audit-report.md | 174 + .../2026-06-10-consistency-layer-design.md | 37 + .../2026-06-10-tiered-extraction-design.md | 45 + ...-07-14-harness-correctness-sweep-design.md | 352 + ...onal-contract-review-adversarial-review.md | 10 + ...contract-review-controller-verification.md | 169 + ...tend-operational-contract-review-report.md | 165 + .../adversarial-review.md | 13 + .../diagram-review.md | 19 + .../evidence-matrix.md | 15 + .../lanes/lane-01-target-review.md | 159 + .../lanes/lane-02-benchmark-patterns.md | 32 + .../per-file-findings.md | 7 + .../priority-recommendations.md | 11 + .../process/implementation_plan.md | 8 + .../process/pre-review-source.md | 509 + .../process/task.md | 7 + .../process/walkthrough.md | 13 + .../sed-proofs.md | 46 + .../unresolved-risk-register.md | 9 + ...nch-note-consistency-adversarial-review.md | 15 + ...ote-consistency-controller-verification.md | 135 + ...keycloak-branch-note-consistency-report.md | 357 + .../adversarial-review.md | 105 + .../application-status.md | 194 + .../evidence-matrix.md | 52 + .../lanes/lane-01-keycloak-sorted-01-10.md | 615 ++ .../lanes/lane-02-keycloak-sorted-11-20.md | 477 + .../lanes/lane-03-keycloak-sorted-21-30.md | 386 + .../lanes/lane-04-keycloak-sorted-31-38.md | 564 ++ .../lanes/lane-05-semantic-risk-sample.md | 69 + .../per-file-findings.md | 193 + .../priority-recommendations.md | 57 + .../process/controller_verify.py | 161 + .../process/implementation_plan.md | 11 + .../process/task.md | 7 + .../process/verify_quotes.py | 80 + .../process/walkthrough.md | 11 + .../sed-proofs.md | 81 + .../unresolved-risk-register.md | 25 + harness/README.md | 147 + .../__pycache__/generate.cpython-312.pyc | Bin 0 -> 36872 bytes .../generate_rules.cpython-312.pyc | Bin 0 -> 9533 bytes .../generate_workflows.cpython-312.pyc | Bin 0 -> 1528 bytes harness/adapters/generate.py | 667 ++ harness/adapters/generate_rules.py | 142 + harness/adapters/generate_workflows.py | 40 + harness/adapters/platform-metadata.json | 355 + .../active_structure_check.cpython-312.pyc | Bin 0 -> 5699 bytes .../branch_contract_check.cpython-312.pyc | Bin 0 -> 20399 bytes .../branch_from_project.cpython-312.pyc | Bin 0 -> 25472 bytes .../contract_markdown.cpython-312.pyc | Bin 0 -> 11245 bytes .../contract_projection.cpython-312.pyc | Bin 0 -> 17013 bytes .../document_commit.cpython-312.pyc | Bin 0 -> 30851 bytes .../execution_profile.cpython-312.pyc | Bin 0 -> 16594 bytes .../__pycache__/fix_bare_refs.cpython-312.pyc | Bin 0 -> 6473 bytes .../fs_transaction.cpython-312.pyc | Bin 0 -> 10395 bytes .../__pycache__/layout_check.cpython-312.pyc | Bin 0 -> 29086 bytes .../migrate_graph_contracts.cpython-312.pyc | Bin 0 -> 29809 bytes .../__pycache__/moc_indexer.cpython-312.pyc | Bin 0 -> 29636 bytes .../proof_hard_gate.cpython-312.pyc | Bin 0 -> 8197 bytes .../proof_manifest.cpython-312.pyc | Bin 0 -> 20911 bytes .../__pycache__/proof_runner.cpython-312.pyc | Bin 0 -> 14832 bytes .../__pycache__/quality_gate.cpython-312.pyc | Bin 0 -> 19179 bytes .../__pycache__/release_gate.cpython-312.pyc | Bin 0 -> 15332 bytes .../semantic_audit.cpython-312.pyc | Bin 0 -> 23729 bytes ...semantic_candidate_builder.cpython-312.pyc | Bin 0 -> 19400 bytes .../semantic_certificate.cpython-312.pyc | Bin 0 -> 25357 bytes .../semantic_regression.cpython-312.pyc | Bin 0 -> 27444 bytes ...semantic_surface_extractor.cpython-312.pyc | Bin 0 -> 25496 bytes .../source_hygiene.cpython-312.pyc | Bin 0 -> 13844 bytes .../template_renderer.cpython-312.pyc | Bin 0 -> 5395 bytes .../typed_contract_check.cpython-312.pyc | Bin 0 -> 46586 bytes .../__pycache__/vault_migrate.cpython-312.pyc | Bin 0 -> 46721 bytes .../workflow_connection_check.cpython-312.pyc | Bin 0 -> 7660 bytes .../workflow_dispatch.cpython-312.pyc | Bin 0 -> 15549 bytes .../runtime/_staging_owasp_csrf/candidate.md | 100 + .../_staging_owasp_csrf/document-commit.json | 15 + .../_staging_owasp_csrf/proof-manifest.json | 146 + .../_staging_owasp_csrf/proof-request.json | 44 + .../_staging_owasp_csrf/proof-summary.md | 7 + .../_staging_owasp_csrf/source-fetch.txt | 26 + harness/runtime/active_structure_check.py | 104 + harness/runtime/branch_contract_check.py | 335 + harness/runtime/branch_from_project.py | 389 + harness/runtime/contract_markdown.py | 193 + harness/runtime/contract_projection.py | 287 + harness/runtime/document_commit.py | 518 + harness/runtime/execution_profile.py | 322 + harness/runtime/fix_bare_refs.py | 104 + harness/runtime/fs_transaction.py | 179 + harness/runtime/layout_check.py | 450 + harness/runtime/migrate_graph_contracts.py | 520 + harness/runtime/moc_indexer.py | 451 + harness/runtime/proof_hard_gate.py | 124 + harness/runtime/proof_manifest.py | 420 + harness/runtime/proof_runner.py | 241 + harness/runtime/quality_gate.py | 370 + harness/runtime/release_gate.py | 385 + harness/runtime/semantic_audit.py | 372 + harness/runtime/semantic_candidate_builder.py | 254 + harness/runtime/semantic_certificate.py | 414 + harness/runtime/semantic_regression.py | 479 + harness/runtime/semantic_surface_extractor.py | 417 + harness/runtime/source_hygiene.py | 249 + harness/runtime/template_renderer.py | 90 + harness/runtime/typed_contract_check.py | 632 ++ harness/runtime/vault_migrate.py | 860 ++ harness/runtime/workflow_connection_check.py | 157 + harness/runtime/workflow_dispatch.py | 316 + .../agents/bodies/branch-depth-auditor.md | 142 + .../source/agents/bodies/coverage-auditor.md | 180 + .../source/agents/bodies/extraction-broker.md | 106 + .../bodies/project-readiness-auditor.md | 103 + .../bodies/wiki-adversarial-reviewer.md | 312 + .../agents/bodies/wiki-consistency-auditor.md | 167 + .../agents/bodies/wiki-decision-researcher.md | 237 + .../agents/bodies/wiki-diagram-reviewer.md | 291 + .../source/agents/bodies/wiki-doc-author.md | 260 + .../agents/bodies/wiki-link-verifier.md | 278 + .../agents/bodies/wiki-research-lane.md | 363 + .../bodies/wiki-semantic-coherence-auditor.md | 66 + .../agents/bodies/wiki-source-summarizer.md | 221 + .../source/agents/branch-depth-auditor.json | 30 + harness/source/agents/coverage-auditor.json | 30 + harness/source/agents/extraction-broker.json | 14 + .../agents/project-readiness-auditor.json | 14 + .../agents/wiki-adversarial-reviewer.json | 30 + .../agents/wiki-consistency-auditor.json | 30 + .../agents/wiki-decision-researcher.json | 30 + .../source/agents/wiki-diagram-reviewer.json | 30 + harness/source/agents/wiki-doc-author.json | 30 + harness/source/agents/wiki-link-verifier.json | 30 + harness/source/agents/wiki-research-lane.json | 30 + .../wiki-semantic-coherence-auditor.json | 15 + .../source/agents/wiki-source-summarizer.json | 30 + .../a11y-report.schema.json | 48 + .../build-manifest.schema.json | 53 + .../bundle-report.schema.json | 48 + .../release-verification.schema.json | 37 + harness/source/document-relations.json | 206 + .../source/document-semantic-surfaces.json | 36 + harness/source/execution-profiles.json | 137 + harness/source/generation-manifest.json | 177 + harness/source/rule-adapters.json | 39 + harness/source/semantic-ontology.json | 47 + harness/source/skills/blogify.md | 49 + harness/source/skills/branch-from-project.md | 48 + harness/source/skills/branch-spec.md | 120 + harness/source/skills/branch.md | 41 + harness/source/skills/coverage.md | 51 + harness/source/skills/daily.md | 27 + harness/source/skills/depth.md | 38 + harness/source/skills/explain.md | 34 + harness/source/skills/ingest.md | 106 + harness/source/skills/interviewize.md | 38 + harness/source/skills/invest-daily.md | 38 + harness/source/skills/invest-decide.md | 24 + harness/source/skills/invest-ingest.md | 15 + harness/source/skills/invest-plan.md | 15 + harness/source/skills/invest-research.md | 35 + harness/source/skills/invest-review.md | 23 + harness/source/skills/lint.md | 168 + harness/source/skills/migrate-claims.md | 119 + harness/source/skills/project-spec.md | 93 + harness/source/skills/project.md | 32 + harness/source/skills/projectize.md | 39 + harness/source/skills/query.md | 34 + harness/source/skills/sync.md | 117 + harness/source/skills/tag.md | 36 + harness/source/typed-contracts.json | 97 + harness/source/vault-layout.json | 8567 +++++++++++++++++ harness/source/workflows/blogify.json | 24 + .../source/workflows/branch-from-project.json | 31 + harness/source/workflows/branch-spec.json | 24 + harness/source/workflows/branch.json | 24 + harness/source/workflows/coverage.json | 24 + harness/source/workflows/daily.json | 24 + harness/source/workflows/depth.json | 24 + harness/source/workflows/explain.json | 24 + harness/source/workflows/ingest.json | 24 + harness/source/workflows/interviewize.json | 24 + harness/source/workflows/invest-daily.json | 16 + harness/source/workflows/invest-decide.json | 16 + harness/source/workflows/invest-ingest.json | 16 + harness/source/workflows/invest-plan.json | 16 + harness/source/workflows/invest-research.json | 16 + harness/source/workflows/invest-review.json | 16 + harness/source/workflows/lint.json | 24 + harness/source/workflows/migrate-claims.json | 24 + harness/source/workflows/project-spec.json | 16 + harness/source/workflows/project.json | 16 + harness/source/workflows/projectize.json | 24 + harness/source/workflows/query.json | 24 + harness/source/workflows/sync.json | 24 + harness/source/workflows/tag.json | 24 + .../samesite-cookie-mdn/candidate.md | 95 + .../samesite-cookie-mdn/document-commit.json | 15 + .../samesite-cookie-mdn/proof-manifest.json | 146 + .../samesite-cookie-mdn/proof-request.json | 49 + .../samesite-cookie-mdn/proof-summary.md | 7 + .../samesite-cookie-mdn/source-fetch.txt | 176 + ...9a460cdf35b7fcb4801e15dd1a65edb594b56.json | 1 + ...109f8fe4f1bc0329ea492e961d447119fd9b6.json | 1 + ...97bf98db56dc0bd283ac9b62174758ca0c76d.json | 1 + ...d3822187ff38fbd04a42c970414d6d47f4e06.json | 1 + ...21c7b9a0028da969bcbbd6dcaa7a25d1fccab.json | 1 + ...e93046b558c1ec42d61a501d77b6bda919e16.json | 1 + ...a0979a8902896d3b6c7845447fee4234cb563.json | 1 + ...3a22b19d736189029c05a94d0b74fc0d88af4.json | 1 + ...0b281a24ddea2406e34c8f41dfb5dbad2f3e5.json | 1 + ...6e70b4ec3718f9d692a56a75fe0f8d88cc977.json | 1 + ...3a049c441b8ff6e50c30e97bb1d32a023a7d0.json | 1 + ...0badcdb36c4cac26674aa701705956383fadb.json | 1 + ...bdf391df37c6b29e981ef49ca22ba3598660f.json | 1 + ...5f8ead3d9260b57a444cb8aa150f15dc8c0bf.json | 1 + ...abccfc0586efc3eb00e5b213f13a578c496e6.json | 1 + ...3789577a309bd926310745c25a0bc14748049.json | 1 + ...cad212e2d7a3fc8c960b1d336bae61022717b.json | 1 + ...6a71a192b1658448419d6ebbf64f939f7c363.json | 1 + ...ructure_check.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 4668 bytes ...est_active_structure_check.cpython-312.pyc | Bin 0 -> 4554 bytes ...ontract_check.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 7489 bytes ...test_branch_contract_check.cpython-312.pyc | Bin 0 -> 7376 bytes ..._from_project.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 17333 bytes .../test_branch_from_project.cpython-312.pyc | Bin 0 -> 21720 bytes ...ct_projection.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 8170 bytes .../test_contract_projection.cpython-312.pyc | Bin 0 -> 8056 bytes ...ver_hardening.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 8544 bytes .../test_cutover_hardening.cpython-312.pyc | Bin 0 -> 8431 bytes ...cument_commit.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 26363 bytes .../test_document_commit.cpython-312.pyc | Bin 0 -> 32415 bytes ...ution_profile.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 9752 bytes .../test_execution_profile.cpython-312.pyc | Bin 0 -> 9638 bytes ...fix_bare_refs.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 3106 bytes .../test_fix_bare_refs.cpython-312.pyc | Bin 0 -> 2992 bytes ...s_transaction.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 11756 bytes .../test_fs_transaction.cpython-312.pyc | Bin 0 -> 11642 bytes ...ate_workflows.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 27772 bytes .../test_generate_workflows.cpython-312.pyc | Bin 0 -> 27658 bytes ...t_korean_lint.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 4890 bytes .../test_korean_lint.cpython-312.pyc | Bin 0 -> 4776 bytes ..._layout_check.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 9188 bytes .../test_layout_check.cpython-312.pyc | Bin 0 -> 9075 bytes ...aph_contracts.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 12995 bytes ...st_migrate_graph_contracts.cpython-312.pyc | Bin 0 -> 12882 bytes ...t_moc_indexer.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 16642 bytes .../test_moc_indexer.cpython-312.pyc | Bin 0 -> 16528 bytes ...document_plan.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 6715 bytes .../test_new_document_plan.cpython-312.pyc | Bin 0 -> 10553 bytes ...oof_hard_gate.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 6952 bytes .../test_proof_hard_gate.cpython-312.pyc | Bin 0 -> 6839 bytes ...roof_manifest.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 10228 bytes .../test_proof_manifest.cpython-312.pyc | Bin 0 -> 10114 bytes ...t_proof_rules.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 4219 bytes .../test_proof_rules.cpython-312.pyc | Bin 0 -> 4105 bytes ..._proof_runner.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 11649 bytes .../test_proof_runner.cpython-312.pyc | Bin 0 -> 11536 bytes ..._quality_gate.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 6954 bytes .../test_quality_gate.cpython-312.pyc | Bin 0 -> 6840 bytes ..._release_gate.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 10942 bytes .../test_release_gate.cpython-312.pyc | Bin 0 -> 10828 bytes ...le_generation.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 3854 bytes .../test_rule_generation.cpython-312.pyc | Bin 0 -> 3740 bytes ...emantic_audit.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 14502 bytes .../test_semantic_audit.cpython-312.pyc | Bin 0 -> 14395 bytes ...idate_builder.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 9530 bytes ...semantic_candidate_builder.cpython-312.pyc | Bin 0 -> 9417 bytes ...c_certificate.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 14440 bytes .../test_semantic_certificate.cpython-312.pyc | Bin 0 -> 14327 bytes ...ic_regression.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 14929 bytes .../test_semantic_regression.cpython-312.pyc | Bin 0 -> 14815 bytes ...ace_extractor.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 8625 bytes ...semantic_surface_extractor.cpython-312.pyc | Bin 0 -> 8512 bytes ...ource_hygiene.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 7598 bytes .../test_source_hygiene.cpython-312.pyc | Bin 0 -> 7485 bytes ...late_renderer.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 4374 bytes .../test_template_renderer.cpython-312.pyc | Bin 0 -> 4260 bytes ...ontract_check.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 12476 bytes .../test_typed_contract_check.cpython-312.pyc | Bin 0 -> 12362 bytes ...vault_migrate.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 19764 bytes .../test_vault_migrate.cpython-312.pyc | Bin 0 -> 19651 bytes ...nection_check.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 4924 bytes ..._workflow_connection_check.cpython-312.pyc | Bin 0 -> 4810 bytes ...flow_dispatch.cpython-312-pytest-9.0.3.pyc | Bin 0 -> 9782 bytes .../test_workflow_dispatch.cpython-312.pyc | Bin 0 -> 9669 bytes harness/tests/fixtures/adapter-snapshots.json | 118 + .../fixtures/legacy-semantic-sha256.json | 153 + .../A1/a1-001-negative.json | 10 + .../A1/a1-001-positive.json | 10 + .../A1/a1-002-negative.json | 10 + .../A1/a1-002-positive.json | 10 + .../A1/a1-003-negative.json | 10 + .../A1/a1-003-positive.json | 10 + .../A1/a1-004-negative.json | 10 + .../A1/a1-004-positive.json | 10 + .../A1/a1-005-negative.json | 10 + .../A1/a1-005-positive.json | 10 + .../A1/a1-006-negative.json | 10 + .../A1/a1-006-positive.json | 10 + .../A1/a1-007-negative.json | 10 + .../A1/a1-007-positive.json | 10 + .../A1/a1-008-negative.json | 10 + .../A1/a1-008-positive.json | 10 + .../A1/a1-009-negative.json | 10 + .../A1/a1-009-positive.json | 10 + .../A1/a1-010-negative.json | 10 + .../A1/a1-010-positive.json | 10 + .../A1/a1-011-negative.json | 10 + .../A1/a1-011-positive.json | 10 + .../A4/a4-001-negative.json | 13 + .../A4/a4-001-positive.json | 19 + .../A4/a4-002-negative.json | 13 + .../A4/a4-002-positive.json | 19 + .../A4/a4-003-negative.json | 13 + .../A4/a4-003-positive.json | 19 + .../A4/a4-004-negative.json | 13 + .../A4/a4-004-positive.json | 19 + .../A4/a4-005-negative.json | 13 + .../A4/a4-005-positive.json | 19 + .../A4/a4-006-negative.json | 13 + .../A4/a4-006-positive.json | 19 + .../A4/a4-007-negative.json | 13 + .../A4/a4-007-positive.json | 19 + .../A4/a4-008-negative.json | 13 + .../A4/a4-008-positive.json | 19 + .../A4/a4-009-negative.json | 13 + .../A4/a4-009-positive.json | 19 + .../A4/a4-010-negative.json | 13 + .../A4/a4-010-positive.json | 19 + .../A4/a4-011-negative.json | 13 + .../A4/a4-011-positive.json | 19 + .../A4/a4-012-negative.json | 13 + .../A4/a4-012-positive.json | 19 + .../D7/d7-001-negative.json | 12 + .../D7/d7-001-positive.json | 18 + .../D7/d7-002-negative.json | 12 + .../D7/d7-002-positive.json | 18 + .../D7/d7-003-negative.json | 12 + .../D7/d7-003-positive.json | 18 + .../D7/d7-004-negative.json | 12 + .../D7/d7-004-positive.json | 18 + .../D7/d7-005-negative.json | 12 + .../D7/d7-005-positive.json | 18 + .../D7/d7-006-negative.json | 12 + .../D7/d7-006-positive.json | 18 + .../D7/d7-007-negative.json | 12 + .../D7/d7-007-positive.json | 18 + .../D7/d7-008-negative.json | 12 + .../D7/d7-008-positive.json | 18 + .../D7/d7-009-negative.json | 12 + .../D7/d7-009-positive.json | 18 + .../D7/d7-010-negative.json | 12 + .../D7/d7-010-positive.json | 18 + .../D7/d7-011-negative.json | 12 + .../D7/d7-011-positive.json | 18 + .../D7/d7-012-negative.json | 12 + .../D7/d7-012-positive.json | 18 + .../DELEG/deleg-001-negative.json | 12 + .../DELEG/deleg-001-positive.json | 12 + .../DELEG/deleg-002-negative.json | 12 + .../DELEG/deleg-002-positive.json | 12 + .../DELEG/deleg-003-negative.json | 12 + .../DELEG/deleg-003-positive.json | 12 + .../DELEG/deleg-004-negative.json | 12 + .../DELEG/deleg-004-positive.json | 12 + .../DELEG/deleg-005-negative.json | 12 + .../DELEG/deleg-005-positive.json | 12 + .../DELEG/deleg-006-negative.json | 12 + .../DELEG/deleg-006-positive.json | 12 + .../DELEG/deleg-007-negative.json | 12 + .../DELEG/deleg-007-positive.json | 12 + .../DELEG/deleg-008-negative.json | 12 + .../DELEG/deleg-008-positive.json | 12 + .../DELEG/deleg-009-negative.json | 12 + .../DELEG/deleg-009-positive.json | 12 + .../DELEG/deleg-010-negative.json | 12 + .../DELEG/deleg-010-positive.json | 12 + .../DELEG/deleg-011-negative.json | 12 + .../DELEG/deleg-011-positive.json | 12 + .../DELEG/deleg-012-negative.json | 12 + .../DELEG/deleg-012-positive.json | 12 + .../E1/e1-001-negative.json | 12 + .../E1/e1-001-positive.json | 12 + .../E1/e1-002-negative.json | 12 + .../E1/e1-002-positive.json | 12 + .../E1/e1-003-negative.json | 12 + .../E1/e1-003-positive.json | 12 + .../E1/e1-004-negative.json | 12 + .../E1/e1-004-positive.json | 12 + .../E1/e1-005-negative.json | 12 + .../E1/e1-005-positive.json | 12 + .../E1/e1-006-negative.json | 12 + .../E1/e1-006-positive.json | 12 + .../E1/e1-007-negative.json | 12 + .../E1/e1-007-positive.json | 12 + .../E1/e1-008-negative.json | 12 + .../E1/e1-008-positive.json | 12 + .../E1/e1-009-negative.json | 12 + .../E1/e1-009-positive.json | 12 + .../E1/e1-010-negative.json | 12 + .../E1/e1-010-positive.json | 12 + .../E1/e1-011-negative.json | 12 + .../E1/e1-011-positive.json | 12 + .../E1/e1-012-negative.json | 12 + .../E1/e1-012-positive.json | 12 + .../HUB/hub-001-negative.json | 10 + .../HUB/hub-001-positive.json | 10 + .../HUB/hub-002-negative.json | 10 + .../HUB/hub-002-positive.json | 10 + .../HUB/hub-003-negative.json | 10 + .../HUB/hub-003-positive.json | 10 + .../HUB/hub-004-negative.json | 10 + .../HUB/hub-004-positive.json | 10 + .../HUB/hub-005-negative.json | 10 + .../HUB/hub-005-positive.json | 10 + .../HUB/hub-006-negative.json | 10 + .../HUB/hub-006-positive.json | 10 + .../HUB/hub-007-negative.json | 10 + .../HUB/hub-007-positive.json | 10 + .../HUB/hub-008-negative.json | 10 + .../HUB/hub-008-positive.json | 10 + .../HUB/hub-009-negative.json | 10 + .../HUB/hub-009-positive.json | 10 + .../HUB/hub-010-negative.json | 10 + .../HUB/hub-010-positive.json | 10 + .../HUB/hub-011-negative.json | 10 + .../HUB/hub-011-positive.json | 10 + .../evaluation-runs/run-1.json | 35 + .../evaluation-runs/run-2.json | 35 + .../evaluation-runs/run-3.json | 35 + .../semantic-consistency/manifest.json | 1360 +++ harness/tests/test_active_structure_check.py | 71 + harness/tests/test_branch_contract_check.py | 130 + harness/tests/test_branch_from_project.py | 305 + harness/tests/test_contract_projection.py | 93 + harness/tests/test_cutover_hardening.py | 110 + harness/tests/test_document_commit.py | 479 + harness/tests/test_execution_profile.py | 148 + harness/tests/test_fix_bare_refs.py | 48 + harness/tests/test_fs_transaction.py | 143 + harness/tests/test_generate_workflows.py | 365 + harness/tests/test_layout_check.py | 144 + harness/tests/test_migrate_graph_contracts.py | 248 + harness/tests/test_moc_indexer.py | 233 + harness/tests/test_new_document_plan.py | 152 + harness/tests/test_proof_hard_gate.py | 104 + harness/tests/test_proof_manifest.py | 142 + harness/tests/test_proof_rules.py | 55 + harness/tests/test_proof_runner.py | 157 + harness/tests/test_quality_gate.py | 109 + harness/tests/test_release_gate.py | 163 + harness/tests/test_rule_generation.py | 49 + harness/tests/test_semantic_audit.py | 202 + .../tests/test_semantic_candidate_builder.py | 146 + harness/tests/test_semantic_certificate.py | 196 + harness/tests/test_semantic_regression.py | 194 + .../tests/test_semantic_surface_extractor.py | 129 + harness/tests/test_source_hygiene.py | 122 + harness/tests/test_template_renderer.py | 50 + harness/tests/test_typed_contract_check.py | 198 + harness/tests/test_vault_migrate.py | 267 + .../tests/test_workflow_connection_check.py | 57 + harness/tests/test_workflow_dispatch.py | 153 + ...feature-template-instantiation-contract.md | 1 + ...nset-header-migration-window-2026-07-02.md | 1 + ...eturn-type-purity-query-port-2026-06-05.md | 1 + ...-typing-cve-2019-14379-block-2026-05-29.md | 1 + ...y-fixture-annotation-pattern-2026-06-02.md | 1 + ...t-violations-as-data-pattern-2026-05-28.md | 1 + ...-clean-architecture-skeleton-2026-07-02.md | 1 + ...on-mapper-responsibility-map-2026-07-02.md | 1 + ...d-router-fail-open-decorator-2026-07-02.md | 1 + ...ter-commit-stampede-contract-2026-07-02.md | 1 + ...e-wiring-vs-policy-ownership-2026-06-20.md | 1 + ...tecture-boundary-enforcement-2026-05-28.md | 1 + ...rchitecture-module-blueprint-2026-05-28.md | 1 + ...e-reference-project-adoption-2026-06-17.md | 1 + ...hema-owner-vs-row-owner-gate-2026-06-20.md | 1 + ...fication-suite-release-gates-2026-07-02.md | 1 + ...-first-java-release-pipeline-2026-06-21.md | 1 + ...-transaction-commit-boundary-2026-07-02.md | 1 + ...s-archunit-fitness-functions-2026-06-05.md | 1 + ...nv-example-drift-gate-gradle-2026-06-06.md | 1 + ...lean-architecture-onboarding-2026-06-25.md | 1 + ...age-local-bootstrap-contract-2026-06-24.md | 1 + ...orization-clean-architecture-2026-06-08.md | 1 + ...cy-security-gate-portability-2026-07-02.md | 1 + ...a21-static-analysis-baseline-2026-06-20.md | 1 + ...ob-constraints-startup-guard-2026-06-09.md | 1 + ...ion-layer-clean-architecture-2026-06-09.md | 1 + ...ance-rule-scoping-by-id-kind-2026-06-01.md | 1 + ...ion-strategy-virtual-threads-2026-07-02.md | 1 + ...nectexception-classification-2026-07-02.md | 1 + ...s-container-oomkill-exit-137-2026-07-02.md | 1 + ...cret-masking-json-vs-pattern-2026-06-14.md | 1 + ...fest-driven-agent-harness-policy-engine.md | 1 + ...resilience4j-functioncounter-2026-07-02.md | 1 + ...-lab-checkoutable-api-replay-2026-07-15.md | 1 + ...lope-meta-category-migration-2026-06-01.md | 1 + ...-metadata-clean-architecture-2026-07-02.md | 1 + ...n-knowledge-capture-workflow-2026-05-28.md | 1 + ...ty-archunit-fitness-function-2026-07-02.md | 1 + ...coverage-junit-contract-test-2026-07-02.md | 1 + ...t-fixture-clean-architecture-2026-06-10.md | 1 + ...xture-dual-mode-build-matrix-2026-06-25.md | 1 + ...e-port-restart-only-rotation-2026-07-02.md | 1 + ...tbox-per-aggregate-fifo-gate-2026-06-11.md | 1 + ...tor-health-probe-group-split-2026-07-02.md | 1 + ...executor-saturation-shutdown-2026-06-13.md | 1 + ...rd-multi-constructor-binding-2026-06-12.md | 1 + ...-serialization-contract-pins-2026-07-02.md | 1 + ...tartup-exit-code-propagation-2026-06-10.md | 1 + ...ty-optional-adapter-template-2026-06-09.md | 1 + ...r-transport-failure-envelope-2026-07-02.md | 1 + ...-filter-layer-error-envelope-2026-06-08.md | 1 + ...e-not-supported-archunit-ban-2026-07-02.md | 1 + ...axonomy-archunit-enforcement-2026-06-19.md | 1 + ...isolation-vendor-default-pin-2026-07-02.md | 1 + ...on-over-spring-transactional-2026-05-28.md | 1 + ...ssion-governance-static-gate-2026-06-20.md | 1 + ...ford-base32-excluded-letters-2026-06-01.md | 1 + ...ceparent-fork-activated-seam-2026-07-02.md | 1 + ...ull-jitter-dlq-observability-2026-07-02.md | 1 + ...ok-signature-replay-contract-2026-07-02.md | 1 + ...-egress-proxy-redirect-block-2026-07-02.md | 1 + .../chore-harness-policy-engine-alignment.md | 1 + raw/branch-notes/chore-ulid-to-uuidv7.md | 1 + .../experiment-nplus1-feed-api-replay.md | 1 + .../experiment-nplus1-highlight-feed.md | 1 + ...feature-accessibility-baseline-contract.md | 1 + ...e-api-client-response-envelope-contract.md | 1 + ...-api-compatibility-deprecation-contract.md | 1 + .../feature-api-contract-baseline.md | 1 + ...ature-application-port-usecase-contract.md | 1 + ...ature-application-query-bypass-contract.md | 1 + .../feature-architecture-enforcement-rules.md | 1 + .../feature-async-ui-state-contract.md | 1 + ...e-authentication-authorization-contract.md | 1 + .../feature-background-job-async-contract.md | 1 + ...ture-boundary-mapper-viewmodel-contract.md | 1 + ...re-boundary-validation-mapping-contract.md | 1 + ...ure-build-release-supply-chain-contract.md | 1 + ...ature-business-rule-validation-contract.md | 1 + .../feature-cache-consistency-contract.md | 1 + ...feature-cachestore-multi-backend-router.md | 1 + .../feature-ci-quality-gates-contract.md | 1 + .../feature-container-runtime-contract.md | 1 + .../feature-contract-registry-governance.md | 1 + ...eature-contract-verification-test-suite.md | 1 + ...feature-data-retention-privacy-contract.md | 1 + ...ature-database-connection-pool-contract.md | 1 + ...dency-vulnerability-management-contract.md | 1 + .../feature-developer-experience-contract.md | 1 + .../feature-distributed-lock-contract.md | 1 + .../feature-distributed-tracing-contract.md | 1 + .../feature-domain-event-outbox-contract.md | 1 + ...ture-domain-feature-onboarding-contract.md | 1 + .../feature-domain-modeling-guardrails.md | 1 + ...eature-env-driven-runtime-configuration.md | 1 + ...feature-file-resource-handling-contract.md | 1 + ...-architecture-enforcement-lint-contract.md | 1 + ...ntend-auth-session-integration-contract.md | 1 + ...tend-browser-security-boundary-contract.md | 1 + ...tend-build-bundle-supply-chain-contract.md | 1 + ...ture-frontend-ci-quality-gates-contract.md | 1 + ...nd-clean-architecture-layering-contract.md | 1 + ...ntend-contract-compatibility-governance.md | 1 + ...e-frontend-contract-registry-governance.md | 1 + ...re-frontend-env-runtime-config-contract.md | 1 + ...-error-classification-boundary-contract.md | 1 + ...nd-observability-logging-trace-contract.md | 1 + ...e-frontend-operational-runbook-contract.md | 1 + ...nd-project-bootstrap-toolchain-contract.md | 1 + ...rontend-release-cache-rollback-contract.md | 1 + ...ntend-render-recovery-boundary-contract.md | 1 + ...ture-frontend-storage-registry-contract.md | 1 + ...feature-frontend-test-taxonomy-contract.md | 1 + ...ture-implementation-readiness-scorecard.md | 1 + .../feature-integration-adapter-templates.md | 1 + ...feature-keycloak-account-linking-spa-ux.md | 1 + ...e-keycloak-account-linking-sub-vs-email.md | 1 + ...ture-keycloak-bff-csrf-samesite-defense.md | 1 + ...eature-keycloak-bff-oauth2login-session.md | 1 + .../feature-keycloak-bff-vs-spa-direct.md | 1 + .../feature-keycloak-docker-compose-stack.md | 1 + ...loak-edge-forwardauth-google-federation.md | 1 + ...ure-keycloak-edge-forwardauth-no-google.md | 1 + ...ure-keycloak-federation-spa-zero-change.md | 1 + ...eature-keycloak-first-broker-login-flow.md | 1 + ...e-keycloak-four-pattern-tradeoff-matrix.md | 1 + ...keycloak-google-claim-attribute-mapping.md | 1 + ...ure-keycloak-google-redirect-uri-policy.md | 1 + ...eature-keycloak-header-spoofing-defense.md | 1 + ...-keycloak-https-termination-caddy-nginx.md | 1 + ...re-keycloak-idp-brokering-google-client.md | 1 + ...ture-keycloak-idp-mappers-claim-to-role.md | 1 + ...k-internal-spa-direct-google-federation.md | 1 + ...-keycloak-internal-spa-direct-no-google.md | 1 + ...re-keycloak-iss-claim-hostname-mismatch.md | 1 + ...keycloak-nginx-auth-request-integration.md | 1 + ...feature-keycloak-oauth2-proxy-oidc-flow.md | 1 + raw/branch-notes/feature-keycloak-patterns.md | 1 + .../feature-keycloak-pkce-flow-stages.md | 1 + ...eature-keycloak-public-domain-tunneling.md | 1 + .../feature-keycloak-realm-client-export.md | 1 + ...re-keycloak-refresh-rotation-and-logout.md | 1 + ...feature-keycloak-refresh-token-rotation.md | 1 + .../feature-keycloak-reverse-proxy-headers.md | 1 + ...e-keycloak-single-ec2-google-federation.md | 1 + .../feature-keycloak-single-ec2-no-google.md | 1 + ...ure-keycloak-spa-token-storage-tradeoff.md | 1 + ...e-keycloak-spring-rs-audience-validator.md | 1 + ...feature-keycloak-spring-rs-role-mapping.md | 1 + .../feature-keycloak-three-leg-trust-chain.md | 1 + ...eycloak-traefik-forwardauth-alternative.md | 1 + .../feature-keycloak-vanilla-js-spa-pkce.md | 1 + .../feature-log-management-contract.md | 1 + ...e-management-actuator-security-contract.md | 1 + .../feature-messaging-multibroker-router.md | 1 + .../feature-metrics-alerting-contract.md | 1 + .../feature-migration-startup-contract.md | 1 + .../feature-notification-provider-spi.md | 1 + ...rational-error-observability-foundation.md | 1 + .../feature-operational-runbook-contract.md | 1 + .../feature-outbound-http-client-baseline.md | 1 + .../feature-persistence-auditing-contract.md | 1 + .../feature-persistence-failure-baseline.md | 1 + ...feature-rate-limit-idempotency-contract.md | 1 + ...e-repository-access-permission-contract.md | 1 + .../feature-resource-identifier-contract.md | 1 + ...ature-routing-navigation-guard-contract.md | 1 + ...re-runtime-context-propagation-contract.md | 1 + ...ature-runtime-health-lifecycle-contract.md | 1 + ...ture-runtime-schema-validation-contract.md | 1 + .../feature-sample-domain-contract-fixture.md | 1 + ...e-sample-feature-slice-contract-fixture.md | 1 + .../feature-sample-portfolio-public-access.md | 1 + ...eature-sample-removal-adoption-contract.md | 1 + .../feature-schema-serialization-contract.md | 1 + .../feature-secrets-config-source-contract.md | 1 + .../feature-security-operational-baseline.md | 1 + .../feature-server-state-caching-contract.md | 1 + ...ure-skeleton-package-blueprint-contract.md | 1 + ...feature-startup-failure-log-suppression.md | 1 + ...eature-static-analysis-quality-contract.md | 1 + .../feature-streaming-response-contract.md | 1 + ...-tailwind-design-token-styling-contract.md | 1 + .../feature-tenant-context-policy.md | 1 + .../feature-test-taxonomy-fixture-contract.md | 1 + ...eature-transaction-concurrency-contract.md | 1 + ...-web-vitals-performance-budget-contract.md | 1 + .../feature-webhook-outbound-contract.md | 1 + ...pter-togglz-ff4j-feature-toggle-library.md | 1 + .../api-versioning-github-rest-date-header.md | 1 + .../api-versioning-stripe-date-based.md | 1 + ...unen-hexagonal-architecture-spring-boot.md | 1 + raw/company-tech-blogs/aws-iam-arn-format.md | 1 + ...ework-transactionmanager-spring-adapter.md | 1 + .../brandur-stripe-idempotency-keys.md | 1 + ...t-lombok-allowlist-direct-transactional.md | 1 + ...ache-woowahan-after-commit-invalidation.md | 1 + ...ci-flaky-test-quarantine-spotify-google.md | 1 + ...launchdarkly-feature-flag-best-practice.md | 1 + ...tainer-woowahan-spring-native-tradeoffs.md | 1 + ...an-architecture-read-path-bypass-wakita.md | 1 + .../curity-bff-pattern-spa.md | 1 + ...urity-oauth2-scope-vs-permission-naming.md | 1 + ...tom-transaction-interceptor-catnipcoder.md | 1 + ...actice-software-developers-redgreencode.md | 1 + ...omain-event-sourcing-vs-cqrs-greg-young.md | 1 + .../domain-woowahan-ddd-aggregate-techblog.md | 1 + ...-architecture-ddd-hexagonal-cqrs-hgraca.md | 1 + ...-sahibinden-package-by-layer-vs-feature.md | 1 + .../file-clamav-icap-gateway-scan.md | 1 + .../github-api-error-format.md | 1 + .../github-graphql-global-node-id.md | 1 + ...al-reflectoring-transactional-placement.md | 1 + .../hexagonal-woowahan-techblog-2023.md | 1 + .../idempotency-brandur-stripe-postgres.md | 1 + .../idempotency-redis-vs-db-storage.md | 1 + .../idempotency-toss-payments-techblog.md | 1 + ...-unknown-kid-refresh-rate-limit-pattern.md | 1 + .../keycloak-google-login-codemancers.md | 1 + ...eycloak-jwt-role-extraction-betweendata.md | 1 + ...ayer-first-kamilmazurek-github-template.md | 1 + ...ibe-advisory-lock-distributed-consensus.md | 1 + ...c-toss-payments-alert-severity-techblog.md | 1 + ...ometer-context-propagation-line-be-hase.md | 1 + ...h-arawn-github-modular-monoliths-spring.md | 1 + .../modulith-kakaobank-techblog-2025.md | 1 + .../multitenancy-atlassian-tenant-context.md | 1 + .../multitenancy-auth0-tenant-resolution.md | 1 + .../multitenancy-hybrid-pooled-siloed-mix.md | 1 + ...itenancy-stripe-citus-schema-per-tenant.md | 1 + ...titenancy-subdomain-resolution-patterns.md | 1 + ...udum-cqrs-separate-read-store-evolution.md | 1 + .../onion-allegro-tech-blog-2023.md | 1 + ...und-stripe-rate-limit-retry-engineering.md | 1 + .../outbox-confluent-kafka-connect-smt.md | 1 + .../outbox-netflix-domain-events-cdc.md | 1 + .../outbox-wix-engineering-debezium.md | 1 + .../outbox-woowahan-techblog-pattern.md | 1 + .../percona-uuid-storage-mysql.md | 1 + .../planetscale-nanoid-api.md | 1 + ...stgresql-slow-query-logging-crunchydata.md | 1 + ...udonymization-hmac-vs-tokenization-iapp.md | 1 + ...-tx-hibernate-optimization-vladmihalcea.md | 1 + ...e-service-experience-woowahan-websocket.md | 1 + ...etry-aws-exponential-backoff-and-jitter.md | 1 + ...unbook-atlassian-gitops-runbook-as-code.md | 1 + .../runbook-woowahan-incident-techblog.md | 1 + ...h-datadog-engineering-graceful-shutdown.md | 1 + ...affolding-backstage-golden-path-spotify.md | 1 + ...lue-structured-concurrency-softwaremill.md | 1 + ...s-1password-developer-secret-references.md | 1 + .../security-toss-actuator-healthcheck.md | 1 + .../security-woowahan-actuator-safe-usage.md | 1 + raw/company-tech-blogs/segment-ksuid.md | 1 + ...senior-engineer-competency-mubin-shaikh.md | 1 + .../skillable-hands-on-lab-structure.md | 1 + ...y-datasource-proxy-spring-boot-galovics.md | 1 + .../snowflake-twitter-id.md | 1 + ...erated-exemption-and-violations-as-data.md | 1 + .../sse-realtime-notification-woowahan.md | 1 + raw/company-tech-blogs/stripe-error-format.md | 1 + .../test-pyramid-vs-trophy-kent-dodds.md | 1 + ...en-hibernate-timestamp-clock-limitation.md | 1 + .../threadlocal-capture-restore-att-israel.md | 1 + .../toss-payments-error-format.md | 1 + .../tracing-datadog-apm-vs-opentelemetry.md | 1 + ...ransaction-port-clean-ddd-spring-medium.md | 1 + ...action-port-vassilis-soum-github-readme.md | 1 + ...alcea-postgresql-audit-logging-triggers.md | 1 + .../woowahan-hexagonal-multimodule.md | 1 + raw/daily-notes/2026-05-27.md | 1 + raw/daily-notes/2026-05-28.md | 1 + raw/daily-notes/2026-06-14.md | 1 + raw/daily-notes/2026-06-30.md | 1 + raw/daily-tasks/README.md | 1 + ...-archunit-controller-domain-return-rule.md | 1 + ...readiness-probe-db-disconnect-detection.md | 1 + .../architecture-deployment-2026-07-18.drawio | 1 + .../architecture-overview-2026-07-18.drawio | 1 + .../architecture-modules-2026-05-26.drawio | 1 + ...tecture-runtime-topology-2026-05-26.drawio | 1 + ...tecture-clean-concentric-2026-07-04.drawio | 1 + ...chitecture-clean-concentric-2026-07-04.svg | 1 + .../architecture-hexagonal-2026-07-04.drawio | 1 + .../architecture-hexagonal-2026-07-04.svg | 1 + .../architecture-layered-2026-07-04.drawio | 1 + .../architecture-layered-2026-07-04.svg | 1 + ...cture-p1a-edge-no-google-2026-05-26.drawio | 1 + ...itecture-p1b-edge-google-2026-05-26.drawio | 1 + ...uster-internal-no-google-2026-05-26.drawio | 1 + ...-cluster-internal-google-2026-05-26.drawio | 1 + ...p3a-single-ec2-no-google-2026-05-26.drawio | 1 + ...re-p3b-single-ec2-google-2026-05-26.drawio | 1 + ...-single-ec2-no-google-2026-05-26-v1.drawio | 1 + ...-single-ec2-no-google-2026-05-26-v2.drawio | 1 + .../architecture-lab-loop-2026-07-20.drawio | 1 + ...patch-auto-approval-rejected-2026-05-28.md | 1 + ...ted-record-accessor-outbound-2026-06-13.md | 1 + ...ion-bean-factory-return-type-2026-06-09.md | 1 + ...archunit-empty-should-anchor-2026-05-27.md | 1 + ...es-empty-vacuous-stale-build-2026-06-20.md | 1 + ...ndom-trace-id-false-positive-2026-06-01.md | 1 + ...cope-sample-ticket-inclusion-2026-05-28.md | 1 + ...estcompileonly-class-loading-2026-06-02.md | 1 + ...trap-postgres-port-collision-2026-06-24.md | 1 + ...dme-subagents-overstrip-runtime-strings.md | 1 + ...ca-gitignored-seed-divergence-at-rebase.md | 1 + ...ca-public-path-snapshot-scope-violation.md | 1 + ...ort-gate-false-positive-shared-contract.md | 1 + ...ting-check-baseline-failures-2026-07-20.md | 1 + ...failed-and-gitignored-config-2026-06-20.md | 1 + ...-universal-column-false-fail-2026-06-20.md | 1 + ...ience-contract-agents-bridge-2026-07-15.md | 1 + ...-migration-set-shared-dev-db-2026-06-12.md | 1 + ...ion-tag-and-dependency-graph-2026-06-20.md | 1 + ...act-missing-jq-job-bootstrap-2026-06-23.md | 1 + ...obal-sed-env-rename-pitfalls-2026-06-06.md | 1 + ...ource-set-isolation-failures-2026-06-25.md | 1 + ...-entry-non-resolvable-config-2026-07-08.md | 1 + ...apper-lock-read-only-sandbox-2026-06-10.md | 1 + ...radle-wrapper-readonly-cache-2026-05-28.md | 1 + .../gradle-wrapper-sandbox-lock-2026-06-25.md | 1 + ...box-lock-readiness-scorecard-2026-06-26.md | 1 + ...n-explain-width-not-narrower-2026-07-13.md | 1 + ...onfetchcount-batch-semantics-2026-07-13.md | 1 + ...3004-collection-fetch-paging-2026-07-13.md | 1 + ...efinition-base-check-failure-2026-07-15.md | 1 + ...expired-row-reclaim-409-loop-2026-06-09.md | 1 + ...retryable-invariant-conflict-2026-06-08.md | 1 + ...lvedaddress-connectexception-2026-06-11.md | 1 + ...sitory-scan-miss-multimodule-2026-06-10.md | 1 + ...d-jvm-test-leak-pii-contract-2026-06-23.md | 1 + ...tion-location-archunit-catch-2026-05-29.md | 1 + ...-jdk-proxy-usecase-injection-2026-06-08.md | 1 + ...-pointcut-final-usecase-bean-2026-06-12.md | 1 + ...acetagvalues-functioncounter-2026-06-11.md | 1 + ...produces-accept-double-fault-2026-06-02.md | 1 + ...ixture-package-path-mismatch-2026-06-25.md | 1 + ...-ambiguous-exception-handler-2026-06-02.md | 1 + ...ortfolio-flyway-out-of-order-2026-06-23.md | 1 + ...2-resource-server-dependency-2026-05-27.md | 1 + ...lio-tomcat-port-in-use-check-2026-07-03.md | 1 + ...2-resource-server-dependency-2026-05-27.md | 1 + ...uild-verification-boundaries-2026-06-21.md | 1 + ...d-reaper-wrong-config-prefix-2026-06-09.md | 1 + ...jre-random-generator-missing-2026-06-24.md | 1 + ...ctor-breaks-webmvctest-slice-2026-06-14.md | 1 + ...ng3-bom-downgrade-noclassdef-2026-06-20.md | 1 + ...four-jackson-three-migration-2026-06-30.md | 1 + ...uctor-no-default-constructor-2026-06-12.md | 1 + ...-test-inner-config-collision-2026-06-17.md | 1 + ...ultimodule-overlap-collision-2026-06-23.md | 1 + ...-config-vs-autoconfiguration-2026-06-17.md | 1 + ...factory-method-not-processed-2026-06-11.md | 1 + ...ftersingletons-null-template-2026-06-13.md | 1 + ...a-flyway-circular-dependency-2026-06-23.md | 1 + ...ng-jpa-postgres-lob-oid-cast-2026-06-23.md | 1 + ...-suppression-spotless-format-2026-07-03.md | 1 + ...text-shared-datasource-close-2026-06-11.md | 1 + ...ockford-u-self-inconsistency-2026-06-01.md | 1 + ...constructor-dep-breaks-slice-2026-06-14.md | 1 + ...figuration-context-pollution-2026-06-01.md | 1 + ...-enum-placeholder-no-default-2026-06-20.md | 1 + ...hunit-manual-importer-vs-analyzeclasses.md | 1 + .../archunit-static-analysis-limits.md | 1 + ...t-violations-as-data-pattern-2026-06-02.md | 1 + ...turation-context-propagation-2026-06-13.md | 1 + ...release-gate-fan-in-blocking-2026-06-20.md | 1 + ...clean-architecture-boundary-enforcement.md | 1 + ...chitecture-domain-onboarding-guardrails.md | 1 + ...lean-architecture-identifier-generation.md | 1 + ...tion-without-spring-coupling-2026-06-08.md | 1 + .../clean-architecture-module-blueprint.md | 1 + ...crown-one-query-vs-cqrs-lite-read-model.md | 1 + ...yncappender-drop-metric-test-2026-06-14.md | 1 + ...digest-first-supply-chain-release-gates.md | 1 + ...modeling-guardrails-archunit-2026-06-05.md | 1 + ...-linter-responsibility-split-2026-06-20.md | 1 + ...dle-sample-off-test-classpath-isolation.md | 1 + ...-rate-limit-design-tradeoffs-2026-06-09.md | 1 + ...grained-error-classification-2026-06-08.md | 1 + ...est-driven-multi-platform-agent-harness.md | 1 + ...tive-query-addscalar-runtime-validation.md | 1 + ...r-envelope-and-observability-foundation.md | 1 + ...r-3-layer-disabled-detection-2026-06-09.md | 1 + .../post-implementation-knowledge-capture.md | 1 + ...ain-contract-fixture-clean-architecture.md | 1 + .../shared-contract-and-sample-isolation.md | 1 + .../single-command-local-bootstrap.md | 1 + ...alization-lifecycle-circular-dependency.md | 1 + ...-fail-fast-config-validation-2026-06-06.md | 1 + ...ransaction-port-vs-spring-transactional.md | 1 + ...x-skip-locked-implementation-2026-06-11.md | 1 + ...sion-dual-control-governance-2026-06-20.md | 1 + raw/invest-daily/.gitkeep | 0 raw/invest-daily/2026-06-06.md | 1 + raw/invest-daily/2026-06-08.md | 1 + raw/invest-ledger/.gitkeep | 0 raw/invest-ledger/ledger.md | 1 + raw/invest-research/.gitkeep | 0 ...-06-05-passive-diversification-behavior.md | 1 + ...-06-05-stoploss-takeprofit-tax-accounts.md | 1 + ...6-08-broad-equity-etf-100man-candidates.md | 1 + ...-06-08-isa-vs-general-account-no-income.md | 1 + ...6-08-korean-broad-etf-ticker-comparison.md | 1 + ...uator-endpoint-exposure-spring-official.md | 1 + .../actuator-istio-sidecar-management-alt.md | 1 + ...ctuator-management-port-spring-official.md | 1 + .../adapter-java-spi-serviceloader.md | 1 + ...r-spring-boot-autoconfig-custom-starter.md | 1 + .../api-versioning-google-aip-180.md | 1 + .../arch-acl-microsoft-pattern.md | 1 + .../arch-clean-architecture-uncle-bob.md | 1 + raw/official-docs/arch-hexagonal-cockburn.md | 1 + ...hunit-annotation-as-registry-evaluation.md | 1 + ...conditional-on-property-3-layer-pattern.md | 1 + raw/official-docs/archunit-user-guide.md | 1 + .../at-transactional-spring-official.md | 1 + raw/official-docs/aws-acm-managed-renewal.md | 1 + ...get-security-group-restriction-official.md | 1 + .../aws-builders-retry-jitter.md | 1 + ...nt-origin-shared-secret-header-official.md | 1 + ...google-iam-permission-naming-convention.md | 1 + ...aws-security-group-referencing-official.md | 1 + .../baggage-otel-baggage-api-spec.md | 1 + raw/official-docs/baggage-w3c-baggage-spec.md | 1 + .../cache-aside-vs-write-through-aws.md | 1 + ...cache-caffeine-asyncloadingcache-readme.md | 1 + .../cache-redisson-rlock-vs-setnx.md | 1 + .../caddy-automatic-https-docs.md | 1 + .../calver-spec-calver-official.md | 1 + raw/official-docs/certbot-user-guide.md | 1 + .../checkstyle-google-style-reference.md | 1 + ...ird-party-cookie-policy-google-official.md | 1 + .../ci-github-actions-vs-gitlab-comparison.md | 1 + .../ci-openapi-snapshot-diff-tooling.md | 1 + .../cloudevents-spec-required-attributes.md | 1 + .../cloudflare-tunnel-routing-official.md | 1 + .../compat-rfc-8594-sunset-header.md | 1 + .../config-12-factor-app-config.md | 1 + ...g-aws-appconfig-feature-flag-deployment.md | 1 + ...-spring-boot-externalized-configuration.md | 1 + ...fig-spring-cloud-config-server-official.md | 1 + ...pring-cloud-kubernetes-configmap-reload.md | 1 + .../container-alpine-java-musl-tradeoffs.md | 1 + .../container-distroless-google-github.md | 1 + ...tainer-graalvm-native-image-spring-boot.md | 1 + ...tainer-stdout-logging-12factor-official.md | 1 + ...gn-keyless-identity-verification-policy.md | 1 + raw/official-docs/cqrs-fowler-bliki.md | 1 + .../cqrs-pattern-azure-architecture-center.md | 1 + raw/official-docs/crockford-base32-spec.md | 1 + raw/official-docs/cuid2-spec.md | 1 + ...asource-micrometer-observation-official.md | 1 + .../datasource-proxy-slow-query-official.md | 1 + ...ndabot-security-updates-gradle-official.md | 1 + ...ependabot-supported-ecosystems-official.md | 1 + .../docker-compose-depends-on-healthcheck.md | 1 + ...compose-networking-extra-hosts-official.md | 1 + ...ker-engine-20-10-release-notes-official.md | 1 + .../docker-host-network-driver-official.md | 1 + ...-port-publishing-loopback-bind-official.md | 1 + raw/official-docs/domain-event-fowler-eaa.md | 1 + .../domain-fowler-anemic-vs-rich-model.md | 1 + .../domain-vaughn-vernon-aggregate-root.md | 1 + ...dual-write-antipattern-microservices-io.md | 1 + .../dx-devcontainer-spring-boot.md | 1 + .../dx-mise-asdf-tool-versioning.md | 1 + .../dx-testcontainers-java-best-practices.md | 1 + ...-awslogs-stdout-cloudwatch-aws-official.md | 1 + .../errorprone-gradle-plugin-readme.md | 1 + ...ent-sourcing-vs-outbox-microservices-io.md | 1 + ...t-uncle-bob-screaming-architecture-2011.md | 1 + raw/official-docs/fetch-spec-cors.md | 1 + .../file-s3-presigned-url-upload.md | 1 + .../file-tus-resumable-upload-protocol.md | 1 + raw/official-docs/find-sec-bugs-official.md | 1 + .../functional-tx-arrow-kt-resource-docs.md | 1 + ...ptographic-erasure-envelope-key-pattern.md | 1 + .../github-dependency-review-action.md | 1 + raw/official-docs/github-webhook-signature.md | 1 + .../google-aip-122-resource-names.md | 1 + .../google-aip-127-http-transcoding.md | 1 + .../google-aip-132-list-method.md | 1 + .../google-aip-136-custom-methods.md | 1 + .../google-aip-148-standard-fields.md | 1 + .../google-aip-151-long-running-operations.md | 1 + .../google-aip-158-pagination.md | 1 + raw/official-docs/google-aip-160-filtering.md | 1 + .../google-aip-185-resource-versioning.md | 1 + .../google-aip-233-batch-create.md | 1 + raw/official-docs/google-antigravity-hooks.md | 1 + raw/official-docs/google-api-error-format.md | 1 + .../google-java-format-readme.md | 1 + ...pp-verification-state-overview-official.md | 1 + ...ogle-oauth-manage-app-audience-official.md | 1 + ...auth2-client-application-types-official.md | 1 + ...olicies-environment-separation-official.md | 1 + ...oauth2-redirect-uri-validation-official.md | 1 + .../google-oauth2-web-server-flow-official.md | 1 + .../google-oidc-discovery-spec.md | 1 + .../google-openid-connect-oidc.md | 1 + .../google-sre-workbook-on-call-monitoring.md | 1 + .../governance-archunit-official.md | 1 + ...adle-java-library-api-vs-implementation.md | 1 + ...eproducible-archives-working-with-files.md | 1 + raw/official-docs/graphql-errors-spec.md | 1 + .../hexagonal-cockburn-wikipedia-summary.md | 1 + .../hexagonal-thombergs-buckpal-github.md | 1 + .../hibernate-slow-query-log-official.md | 1 + .../iana-media-types-registry.md | 1 + .../idempotency-aws-lambda-powertools.md | 1 + raw/official-docs/idempotency-ietf-draft.md | 1 + .../idempotency-no-api-level-github-rest.md | 1 + raw/official-docs/idempotency-paypal-docs.md | 1 + raw/official-docs/idempotency-square-api.md | 1 + .../idempotency-stripe-api-ref.md | 1 + .../istio-mtls-cert-rotation-official.md | 1 + raw/official-docs/jdk-files-createtempfile.md | 1 + .../jdk21-threadpoolexecutor-javadoc.md | 1 + raw/official-docs/json-api-errors-spec.md | 1 + .../jsonapi-pagination-format.md | 1 + ...it5-conditional-env-variable-user-guide.md | 1 + ...ks-keycloak-key-rotation-active-passive.md | 1 + ...ose-jwksourcebuilder-spring-integration.md | 1 + ...lication-security-checklist-readonly-fs.md | 1 + .../k8s-configure-probes-task-page.md | 1 + ...ogging-architecture-kubernetes-official.md | 1 + .../k8s-network-policy-official.md | 1 + .../k8s-pod-lifecycle-probes-concept.md | 1 + .../k8s-pod-security-standards-restricted.md | 1 + ...cloak-2500-hostname-v2-release-official.md | 1 + ...cloak-2600-hostname-v1-removed-official.md | 1 + ...t-console-unlink-lockout-guard-official.md | 1 + ...thorization-services-realm-client-roles.md | 1 + ...ycloak-client-initiated-account-linking.md | 1 + ...client-pkce-method-enforcement-official.md | 1 + .../keycloak-configuring-database.md | 1 + .../keycloak-first-broker-login-flow.md | 1 + ...er-login-verify-authenticators-official.md | 1 + .../keycloak-first-login-flow.md | 1 + .../keycloak-getting-started-docker.md | 1 + .../keycloak-google-idp-setup.md | 1 + raw/official-docs/keycloak-health-checks.md | 1 + .../keycloak-hostname-configuration.md | 1 + .../keycloak-identity-broker-spi.md | 1 + ...ak-identity-brokering-overview-official.md | 1 + .../keycloak-identity-provider-mappers.md | 1 + ...rovider-redirector-default-idp-official.md | 1 + ...ak-identity-provider-sync-mode-official.md | 1 + ...-identity-provider-trust-email-official.md | 1 + ...-idp-hide-on-login-page-toggle-official.md | 1 + ...loak-idp-hint-client-suggested-official.md | 1 + .../keycloak-import-export-realms.md | 1 + .../keycloak-oidc-logout-endpoint-official.md | 1 + ...esh-token-rotation-reuse-admin-official.md | 1 + ...efresh-token-rotation-sessions-official.md | 1 + .../keycloak-reverseproxy-official.md | 1 + ...eycloak-securing-apps-overview-official.md | 1 + .../keycloak-server-containers-docker.md | 1 + ...tes-exit-code-observability-termination.md | 1 + .../kubernetes-pod-lifecycle-termination.md | 1 + ...baeldung-clean-architecture-spring-boot.md | 1 + .../lock-postgres-advisory-locks.md | 1 + ...ck-shedlock-issue-899-non-scheduler-use.md | 1 + raw/official-docs/lock-shedlock-readme.md | 1 + .../lock-spring-integration-lock-registry.md | 1 + .../log-ecs-schema-elastic-official.md | 1 + ...logback-mask-pattern-converter-official.md | 1 + .../log-otel-log-data-model-spec.md | 1 + .../lombok-builder-data-features-official.md | 1 + raw/official-docs/lychee-link-checker.md | 1 + ...mapstruct-generated-annotation-official.md | 1 + ...-google-ewaschuk-philosophy-on-alerting.md | 1 + .../metric-google-sre-slo-burn-rate.md | 1 + .../metric-google-sre-workbook-on-call.md | 1 + ...crometer-high-cardinality-tags-detector.md | 1 + ...icrometer-histogram-percentile-concepts.md | 1 + ...c-micrometer-naming-convention-official.md | 1 + .../metric-otel-metrics-data-model-spec.md | 1 + ...theus-histograms-vs-summaries-practices.md | 1 + ...etheus-label-cardinality-best-practices.md | 1 + ...micrometer-context-propagation-official.md | 1 + ...opagation-purpose-thread-local-accessor.md | 1 + .../microservices-io-transactional-outbox.md | 1 + .../migration-atlas-schema-as-code.md | 1 + ...ion-flyway-official-concepts-and-repair.md | 1 + ...igration-k8s-init-container-job-pattern.md | 1 + ...n-liquibase-official-changelog-xml-yaml.md | 1 + .../modulith-spring-official-doc.md | 1 + ...cy-aws-saas-tenant-isolation-whitepaper.md | 1 + ...ultitenancy-azure-architecture-patterns.md | 1 + .../multitenancy-hibernate-user-guide.md | 1 + .../multitenancy-microservices-io-pattern.md | 1 + ...l-innodb-transaction-isolation-official.md | 1 + raw/official-docs/nanoid-spec.md | 1 + .../nginx-auth-request-module-official.md | 1 + .../nginx-client-max-body-size.md | 1 + ...-core-module-location-internal-official.md | 1 + .../ngrok-http-tunnel-official.md | 1 + raw/official-docs/oauth-v2-1-draft-ietf.md | 1 + .../oauth2-browser-based-apps-ietf-draft.md | 1 + raw/official-docs/oauth2-pkce-rfc-7636.md | 1 + ...oxy-behaviour-cookie-vs-bearer-official.md | 1 + ...h2-proxy-cookie-redirect-flags-official.md | 1 + .../oauth2-proxy-endpoints-official.md | 1 + ...oauth2-proxy-endpoints-signout-official.md | 1 + ...2-proxy-keycloak-oidc-provider-official.md | 1 + ...oauth2-proxy-nginx-integration-official.md | 1 + .../oauth2-proxy-overview-config-official.md | 1 + .../oauth2-proxy-session-storage-official.md | 1 + .../oauth2-token-revocation-rfc-7009.md | 1 + raw/official-docs/oidc-client-ts-library.md | 1 + .../onion-palermo-original-2008.md | 1 + raw/official-docs/openapi-spec-3-1-0.md | 1 + ...openid-connect-core-id-token-validation.md | 1 + .../openjdk-jdk-8196595-container-support.md | 1 + ...ntelemetry-http-semconv-migration-guide.md | 1 + ...opentelemetry-versioning-stability-spec.md | 1 + .../otel-exceptions-semantic-conventions.md | 1 + .../outbound-openfeign-declarative-client.md | 1 + .../outbound-resilience4j-vs-spring-retry.md | 1 + .../outbound-spring-restclient-baseline.md | 1 + ...outbound-webclient-vs-restclient-spring.md | 1 + .../outbox-debezium-official-docs.md | 1 + .../outbox-skip-locked-microservices-io.md | 1 + .../owasp-authz-permission-model-abac-rbac.md | 1 + ...asp-content-security-policy-cheat-sheet.md | 1 + .../owasp-file-upload-cheat-sheet.md | 1 + raw/official-docs/owasp-hsts-cheat-sheet.md | 1 + .../owasp-html5-storage-xss-spa.md | 1 + .../owasp-logging-cheat-sheet.md | 1 + raw/official-docs/owasp-path-traversal.md | 1 + raw/official-docs/owasp-ssrf-prevention.md | 1 + .../p6spy-configuration-official.md | 1 + raw/official-docs/patch-json-merge-rfc7396.md | 1 + ...ersistence-hikaricp-configuration-knobs.md | 1 + .../persistence-hikaricp-pool-sizing-wiki.md | 1 + ...osiv-antipattern-hibernate-vladmihalcea.md | 1 + .../persistence-r2dbc-reactive-spring.md | 1 + ...ce-spring-dataaccessexception-hierarchy.md | 1 + ...postgres-transaction-isolation-official.md | 1 + .../postgresql-slow-query-log-official.md | 1 + ...acy-cryptographic-erasure-nist-sp800-88.md | 1 + .../privacy-gdpr-article-25-design.md | 1 + raw/official-docs/problem-detail-rfc-7807.md | 1 + .../prometheus-alertmanager-silences.md | 1 + ...obuf-reserved-vs-json-openapi-extension.md | 1 + .../proxy-pass-request-body-nginx-official.md | 1 + raw/official-docs/react-router-official.md | 1 + .../react-ui-library-official.md | 1 + ...dhat-openjdk-container-awareness-java17.md | 1 + raw/official-docs/registry-adr-official.md | 1 + .../renovate-gradle-manager-official.md | 1 + ...te-vulnerability-alerts-gradle-official.md | 1 + .../reproducible-builds-org-jvm-guide.md | 1 + .../resilience4j-micrometer-module.md | 1 + .../retry-aws-well-architected-rel05-bp03.md | 1 + ...ry-spring-retry-readme-backoff-defaults.md | 1 + raw/official-docs/rfc3339-datetime-utc.md | 1 + .../rfc3986-uri-generic-syntax.md | 1 + raw/official-docs/rfc6455-websocket.md | 1 + .../rfc8996-tls10-tls11-deprecation.md | 1 + raw/official-docs/rfc9110-http-semantics.md | 1 + raw/official-docs/rfc9111-http-caching.md | 1 + .../rfc9112-http-1-1-chunked-transfer.md | 1 + .../rfc9421-http-message-signatures.md | 1 + .../rfc9457-problem-details-http-apis.md | 1 + raw/official-docs/rfc9562-uuid.md | 1 + ...runbook-pagerduty-incident-response-doc.md | 1 + .../runtime-health-istio-mesh-health-check.md | 1 + .../runtime-health-k8s-probes-official.md | 1 + .../runtime-health-spring-actuator-groups.md | 1 + .../runtime-spring-boot-virtual-threads.md | 1 + ...ample-microservices-spring-cloud-github.md | 1 + .../sample-realworld-gothinkster-github.md | 1 + .../sample-spring-petclinic-github.md | 1 + .../scaffolding-cookiecutter-official.md | 1 + .../scaffolding-degit-svelte-github.md | 1 + .../scaffolding-github-template-repository.md | 1 + .../scaffolding-spring-initializr.md | 1 + .../schema-avro-evolution-rules.md | 1 + ...ema-bigdecimal-money-serialization-java.md | 1 + ...ema-jackson-polymorphic-deserialization.md | 1 + .../schema-jackson-unknown-field-handling.md | 1 + .../schema-protobuf-vs-json-evolution.md | 1 + .../scoped-value-jep-446-506-openjdk.md | 1 + .../scorecard-aws-well-architected.md | 1 + .../scorecard-cis-benchmarks-slsa.md | 1 + .../scorecard-opentelemetry-maturity.md | 1 + .../secrets-aws-secrets-manager-rotation.md | 1 + ...ts-k8s-secret-external-secrets-operator.md | 1 + ...secrets-vault-dynamic-secrets-hashicorp.md | 1 + ...security-authorization-cheatsheet-owasp.md | 1 + .../security-aws-sigv4-hmac-signing.md | 1 + .../security-jwt-rfc-7519-validation.md | 1 + raw/official-docs/security-mtls-rfc-8705.md | 1 + .../security-oauth2-pkce-rfc-8252.md | 1 + .../security-opa-policy-engine-official.md | 1 + ...ring-jwt-timestamp-validator-clock-skew.md | 1 + .../semver-2-0-0-spec-semver-official.md | 1 + ...o-third-party-cookies-keycloak-official.md | 1 + raw/official-docs/skip-locked-mysql-docs.md | 1 + .../skip-locked-postgres-docs.md | 1 + .../slsa-v1-provenance-schema.md | 1 + .../sonarqube-server-versus-cloud.md | 1 + .../spotbugs-gradle-plugin-docs.md | 1 + .../spotless-gradle-plugin-readme.md | 1 + ...oot-exit-code-generator-startup-failure.md | 1 + ...spring-boot-graceful-shutdown-reference.md | 1 + .../spring-boot-multipart-reference.md | 1 + .../spring-boot-structuring-your-code.md | 1 + ...oot-task-execution-scheduling-reference.md | 1 + ...-slices-webmvctest-datajpatest-official.md | 1 + .../spring-data-jpa-auditing-official.md | 1 + ...spring-data-jpa-enable-jpa-auditing-api.md | 1 + ...ng-data-jpa-projections-spring-official.md | 1 + ...ta-jpa-transactionality-spring-official.md | 1 + .../spring-data-pageable-defaults.md | 1 + ...-executor-configuration-support-javadoc.md | 1 + ...lity-context-propagating-task-decorator.md | 1 + ...ework-test-enabledif-jupiter-annotation.md | 1 + ...ramework-threadpooltaskexecutor-javadoc.md | 1 + .../spring-mvc-async-streaming.md | 1 + .../spring-mvc-rest-exception-handling.md | 1 + raw/official-docs/spring-problem-detail.md | 1 + .../spring-restclient-builder-reference.md | 1 + ...ing-security-authorization-architecture.md | 1 + ...security-authorization-defense-in-depth.md | 1 + ...spring-security-authorize-http-requests.md | 1 + ...cy-delegating-security-context-executor.md | 1 + .../spring-security-method-security.md | 1 + ...ty-nested-authorities-claim-issue-15201.md | 1 + .../spring-security-resource-server-jwt.md | 1 + .../spring-smartlifecycle-reference.md | 1 + .../spring-streaming-response-body.md | 1 + ...saction-synchronization-manager-javadoc.md | 1 + .../spring-transactional-event-listener.md | 1 + .../spring-tx-management-reference.md | 1 + ...ropagation-required-new-nested-official.md | 1 + .../stripe-resource-id-convention.md | 1 + raw/official-docs/stripe-webhook-signature.md | 1 + ...sunset-deprecation-headers-paired-usage.md | 1 + .../supply-chain-cosign-keyless-sigstore.md | 1 + ...hain-gradle-vs-maven-dependency-locking.md | 1 + .../supply-chain-slsa-provenance-framework.md | 1 + .../svix-webhook-best-practices.md | 1 + .../sysexits-bsd-exit-code-convention.md | 1 + .../tailwind-css-utility-first-official.md | 1 + .../tanstack-query-server-state-official.md | 1 + .../test-taxonomy-practical-pyramid-fowler.md | 1 + .../test-taxonomy-testcontainers-official.md | 1 + ...-cookie-blocking-safari-webkit-official.md | 1 + ...readlocal-virtual-threads-java21-oracle.md | 1 + .../trace-context-w3c-recommendation.md | 1 + .../tracing-b3-propagation-zipkin-spec.md | 1 + ...ing-micrometer-observation-introduction.md | 1 + ...tracing-otel-sampling-tail-vs-head-spec.md | 1 + .../tracing-otel-trace-api-spec.md | 1 + ...pring-boot-3-actuator-tracing-reference.md | 1 + .../tracing-w3c-trace-context-spec.md | 1 + ...traefik-forwardauth-middleware-official.md | 1 + .../traefik-hub-oidc-middleware-official.md | 1 + ...community-plugin-lukaszraczylo-official.md | 1 + .../transaction-template-spring-official.md | 1 + ...tional-outbox-aws-prescriptive-guidance.md | 1 + .../trivy-action-github-actions.md | 1 + .../trivy-filtering-suppression-policy.md | 1 + .../trivy-java-language-coverage.md | 1 + .../trivy-severity-exit-code-gating.md | 1 + raw/official-docs/ulid-spec.md | 1 + ...dation-jakarta-bean-validation-3.0-spec.md | 1 + ...ication-approvaltests-snapshot-official.md | 1 + .../verification-pact-cdc-official.md | 1 + ...fication-spring-cloud-contract-official.md | 1 + .../verification-spring-restdocs-official.md | 1 + raw/official-docs/vite-build-tool-official.md | 1 + ...vuln-severity-cisa-kev-catalog-official.md | 1 + ...n-severity-cvss-v31-spec-first-official.md | 1 + .../whatwg-html-server-sent-events.md | 1 + .../zod-runtime-schema-validation-official.md | 1 + ...-skeleton-frontend-operational-contract.md | 1 + .../ca-skeleton-operational-contract.md | 1 + raw/project-notes/invest-money-flow-system.md | 1 + .../keycloak-patterns-overview.md | 1 + .../llm-wiki-server-migration.md | 1 + raw/project-notes/nplus1-presentation-prep.md | 1 + raw/project-notes/project-infra-overview.md | 1 + rules/advisory-depth.md | 1 + rules/branch-depth-gate.md | 1 + rules/consistency-contract.md | 1 + rules/coverage-gate.md | 1 + rules/diagram-standards.md | 1 + rules/evidence-first-research.md | 1 + rules/execution-profiles.md | 1 + rules/extraction-tiering.md | 1 + rules/linking-rules.md | 1 + rules/naming-conventions.md | 1 + rules/project-readiness-gate.md | 1 + rules/prose-style.md | 1 + rules/reporting-standards.md | 1 + rules/subagent-input-contracts.md | 1 + rules/tag-taxonomy.md | 1 + scripts/deep-research/.gitignore | 5 + scripts/deep-research/README.md | 42 + .../deep-research/deep_research/__init__.py | 0 .../deep-research/deep_research/__main__.py | 43 + .../deep_research/backends/__init__.py | 0 .../deep_research/backends/antigravity.py | 72 + .../deep_research/backends/base.py | 11 + .../deep_research/backends/codex.py | 89 + .../deep_research/backends/mock.py | 21 + scripts/deep-research/deep_research/config.py | 15 + scripts/deep-research/deep_research/core.py | 122 + .../deep-research/deep_research/extract.py | 217 + .../deep-research/deep_research/pipeline.py | 130 + .../deep-research/deep_research/prompts.py | 86 + scripts/deep-research/deep_research/report.py | 43 + .../deep-research/deep_research/schemas.py | 60 + scripts/deep-research/deep_research/vote.py | 125 + scripts/deep-research/pyproject.toml | 20 + scripts/deep-research/tests/__init__.py | 0 scripts/deep-research/tests/test_core.py | 153 + .../deep-research/tests/test_extract_vote.py | 131 + .../deep-research/tests/test_pipeline_mock.py | 136 + templates/blog-template.md | 1 + templates/blog-topic-template.md | 1 + templates/branch-note-template.md | 1 + templates/branch-report-template.md | 1 + templates/concept-template.md | 1 + templates/daily-note-template.md | 1 + templates/daily-task-develop-template.md | 1 + templates/daily-task-infra-template.md | 1 + templates/error-note-template.md | 1 + templates/explainer-template.md | 1 + templates/interview-prep-template.md | 1 + templates/interview-template.md | 1 + templates/invest-concept-template.md | 1 + templates/invest-daily-template.md | 1 + templates/invest-field-card-template.md | 1 + templates/invest-ledger-template.md | 1 + templates/invest-plan-template.md | 1 + templates/invest-research-template.md | 1 + templates/invest-strategy-template.md | 1 + templates/job-posting-template.md | 1 + templates/lecture-note-template.md | 1 + templates/portfolio-template.md | 1 + templates/project-report-template.md | 1 + templates/project-template.md | 1 + templates/raw-source-template.md | 1 + templates/source-summary-template.md | 1 + templates/wiki-project-template.md | 1 + vault/00-system/.gitkeep | 1 + vault/00-system/rules/advisory-depth.md | 379 + vault/00-system/rules/branch-depth-gate.md | 66 + vault/00-system/rules/consistency-contract.md | 87 + vault/00-system/rules/coverage-gate.md | 83 + vault/00-system/rules/diagram-standards.md | 379 + .../rules/evidence-first-research.md | 152 + vault/00-system/rules/execution-profiles.md | 80 + vault/00-system/rules/extraction-tiering.md | 41 + vault/00-system/rules/linking-rules.md | 241 + vault/00-system/rules/naming-conventions.md | 280 + .../00-system/rules/project-readiness-gate.md | 92 + vault/00-system/rules/prose-style.md | 40 + vault/00-system/rules/reporting-standards.md | 564 ++ .../rules/subagent-input-contracts.md | 87 + vault/00-system/rules/tag-taxonomy.md | 105 + vault/00-system/templates/blog-template.md | 116 + .../templates/blog-topic-template.md | 110 + .../templates/branch-note-template.md | 473 + .../templates/branch-report-template.md | 387 + vault/00-system/templates/concept-template.md | 66 + .../templates/daily-note-template.md | 62 + .../templates/daily-task-develop-template.md | 191 + .../templates/daily-task-infra-template.md | 238 + .../templates/error-note-template.md | 98 + .../00-system/templates/explainer-template.md | 129 + .../templates/interview-prep-template.md | 93 + .../00-system/templates/interview-template.md | 68 + .../templates/invest-concept-template.md | 51 + .../templates/invest-daily-template.md | 67 + .../templates/invest-field-card-template.md | 65 + .../templates/invest-ledger-template.md | 46 + .../templates/invest-plan-template.md | 100 + .../templates/invest-research-template.md | 60 + .../templates/invest-strategy-template.md | 65 + .../templates/job-posting-template.md | 98 + .../templates/lecture-note-template.md | 91 + .../00-system/templates/portfolio-template.md | 118 + .../templates/project-report-template.md | 279 + vault/00-system/templates/project-template.md | 468 + .../templates/raw-source-template.md | 106 + .../templates/source-summary-template.md | 64 + .../templates/wiki-project-template.md | 51 + vault/10-projects/.gitkeep | 1 + ...feature-accessibility-baseline-contract.md | 289 + ...e-api-client-response-envelope-contract.md | 401 + .../feature-async-ui-state-contract.md | 364 + ...ture-boundary-mapper-viewmodel-contract.md | 281 + ...-architecture-enforcement-lint-contract.md | 312 + ...ntend-auth-session-integration-contract.md | 316 + ...tend-browser-security-boundary-contract.md | 345 + ...tend-build-bundle-supply-chain-contract.md | 345 + ...ture-frontend-ci-quality-gates-contract.md | 307 + ...nd-clean-architecture-layering-contract.md | 287 + ...ntend-contract-compatibility-governance.md | 292 + ...e-frontend-contract-registry-governance.md | 302 + ...re-frontend-env-runtime-config-contract.md | 396 + ...-error-classification-boundary-contract.md | 344 + ...nd-observability-logging-trace-contract.md | 378 + ...e-frontend-operational-runbook-contract.md | 268 + ...nd-project-bootstrap-toolchain-contract.md | 307 + ...rontend-release-cache-rollback-contract.md | 285 + ...ntend-render-recovery-boundary-contract.md | 336 + ...ture-frontend-storage-registry-contract.md | 295 + ...feature-frontend-test-taxonomy-contract.md | 352 + ...ature-routing-navigation-guard-contract.md | 313 + ...ture-runtime-schema-validation-contract.md | 293 + ...e-sample-feature-slice-contract-fixture.md | 318 + .../feature-server-state-caching-contract.md | 304 + ...-tailwind-design-token-styling-contract.md | 309 + ...-web-vitals-performance-budget-contract.md | 260 + ...-skeleton-frontend-operational-contract.md | 2420 +++++ .../chore-harness-policy-engine-alignment.md | 249 + .../branch-notes/chore-ulid-to-uuidv7.md | 191 + ...-api-compatibility-deprecation-contract.md | 261 + .../feature-api-contract-baseline.md | 583 ++ ...ature-application-port-usecase-contract.md | 425 + ...ature-application-query-bypass-contract.md | 421 + .../feature-architecture-enforcement-rules.md | 392 + ...e-authentication-authorization-contract.md | 407 + .../feature-background-job-async-contract.md | 468 + ...re-boundary-validation-mapping-contract.md | 477 + ...ure-build-release-supply-chain-contract.md | 503 + ...ature-business-rule-validation-contract.md | 373 + .../feature-cache-consistency-contract.md | 252 + ...feature-cachestore-multi-backend-router.md | 200 + .../feature-ci-quality-gates-contract.md | 422 + .../feature-container-runtime-contract.md | 444 + .../feature-contract-registry-governance.md | 386 + ...eature-contract-verification-test-suite.md | 427 + ...feature-data-retention-privacy-contract.md | 276 + ...ature-database-connection-pool-contract.md | 371 + ...dency-vulnerability-management-contract.md | 493 + .../feature-developer-experience-contract.md | 443 + .../feature-distributed-lock-contract.md | 445 + .../feature-distributed-tracing-contract.md | 401 + .../feature-domain-event-outbox-contract.md | 523 + ...ture-domain-feature-onboarding-contract.md | 426 + .../feature-domain-modeling-guardrails.md | 411 + ...eature-env-driven-runtime-configuration.md | 431 + ...feature-file-resource-handling-contract.md | 260 + ...ture-implementation-readiness-scorecard.md | 365 + .../feature-integration-adapter-templates.md | 412 + .../feature-log-management-contract.md | 430 + ...e-management-actuator-security-contract.md | 424 + .../feature-messaging-multibroker-router.md | 175 + .../feature-metrics-alerting-contract.md | 458 + .../feature-migration-startup-contract.md | 374 + .../feature-notification-provider-spi.md | 261 + ...rational-error-observability-foundation.md | 602 ++ .../feature-operational-runbook-contract.md | 377 + .../feature-outbound-http-client-baseline.md | 482 + .../feature-persistence-auditing-contract.md | 382 + .../feature-persistence-failure-baseline.md | 358 + ...feature-rate-limit-idempotency-contract.md | 452 + ...e-repository-access-permission-contract.md | 443 + .../feature-resource-identifier-contract.md | 995 ++ ...re-runtime-context-propagation-contract.md | 358 + ...ature-runtime-health-lifecycle-contract.md | 505 + .../feature-sample-domain-contract-fixture.md | 383 + .../feature-sample-portfolio-public-access.md | 215 + ...eature-sample-removal-adoption-contract.md | 338 + .../feature-schema-serialization-contract.md | 381 + .../feature-secrets-config-source-contract.md | 410 + .../feature-security-operational-baseline.md | 490 + ...ure-skeleton-package-blueprint-contract.md | 495 + ...feature-startup-failure-log-suppression.md | 291 + ...eature-static-analysis-quality-contract.md | 450 + .../feature-streaming-response-contract.md | 312 + .../feature-tenant-context-policy.md | 261 + .../feature-test-taxonomy-fixture-contract.md | 461 + ...eature-transaction-concurrency-contract.md | 393 + .../feature-webhook-outbound-contract.md | 480 + .../ca-skeleton-operational-contract.md | 2890 ++++++ .../architecture-deployment-2026-07-18.drawio | 51 + .../architecture-overview-2026-07-18.drawio | 59 + .../architecture-modules-2026-05-26.drawio | 97 + ...tecture-runtime-topology-2026-05-26.drawio | 100 + ...tecture-clean-concentric-2026-07-04.drawio | 52 + ...chitecture-clean-concentric-2026-07-04.svg | 48 + .../architecture-hexagonal-2026-07-04.drawio | 62 + .../architecture-hexagonal-2026-07-04.svg | 65 + .../architecture-layered-2026-07-04.drawio | 48 + .../architecture-layered-2026-07-04.svg | 48 + ...cture-p1a-edge-no-google-2026-05-26.drawio | 89 + ...itecture-p1b-edge-google-2026-05-26.drawio | 92 + ...uster-internal-no-google-2026-05-26.drawio | 80 + ...-cluster-internal-google-2026-05-26.drawio | 88 + ...p3a-single-ec2-no-google-2026-05-26.drawio | 105 + ...re-p3b-single-ec2-google-2026-05-26.drawio | 106 + ...-single-ec2-no-google-2026-05-26-v1.drawio | 113 + ...-single-ec2-no-google-2026-05-26-v2.drawio | 231 + .../architecture-lab-loop-2026-07-20.drawio | 52 + ...patch-auto-approval-rejected-2026-05-28.md | 69 + ...ted-record-accessor-outbound-2026-06-13.md | 60 + ...ion-bean-factory-return-type-2026-06-09.md | 57 + ...archunit-empty-should-anchor-2026-05-27.md | 75 + ...es-empty-vacuous-stale-build-2026-06-20.md | 52 + ...ndom-trace-id-false-positive-2026-06-01.md | 64 + ...cope-sample-ticket-inclusion-2026-05-28.md | 118 + ...estcompileonly-class-loading-2026-06-02.md | 122 + ...trap-postgres-port-collision-2026-06-24.md | 68 + ...dme-subagents-overstrip-runtime-strings.md | 74 + ...ca-gitignored-seed-divergence-at-rebase.md | 32 + ...ca-public-path-snapshot-scope-violation.md | 41 + ...ort-gate-false-positive-shared-contract.md | 81 + ...ting-check-baseline-failures-2026-07-20.md | 69 + ...failed-and-gitignored-config-2026-06-20.md | 91 + ...-universal-column-false-fail-2026-06-20.md | 65 + ...ience-contract-agents-bridge-2026-07-15.md | 80 + ...-migration-set-shared-dev-db-2026-06-12.md | 73 + ...ion-tag-and-dependency-graph-2026-06-20.md | 104 + ...act-missing-jq-job-bootstrap-2026-06-23.md | 87 + ...obal-sed-env-rename-pitfalls-2026-06-06.md | 55 + ...ource-set-isolation-failures-2026-06-25.md | 45 + ...-entry-non-resolvable-config-2026-07-08.md | 62 + ...apper-lock-read-only-sandbox-2026-06-10.md | 65 + ...radle-wrapper-readonly-cache-2026-05-28.md | 73 + .../gradle-wrapper-sandbox-lock-2026-06-25.md | 67 + ...box-lock-readiness-scorecard-2026-06-26.md | 59 + ...n-explain-width-not-narrower-2026-07-13.md | 53 + ...onfetchcount-batch-semantics-2026-07-13.md | 54 + ...3004-collection-fetch-paging-2026-07-13.md | 59 + ...efinition-base-check-failure-2026-07-15.md | 73 + ...expired-row-reclaim-409-loop-2026-06-09.md | 45 + ...retryable-invariant-conflict-2026-06-08.md | 46 + ...lvedaddress-connectexception-2026-06-11.md | 67 + ...sitory-scan-miss-multimodule-2026-06-10.md | 104 + ...d-jvm-test-leak-pii-contract-2026-06-23.md | 84 + ...tion-location-archunit-catch-2026-05-29.md | 58 + ...-jdk-proxy-usecase-injection-2026-06-08.md | 66 + ...-pointcut-final-usecase-bean-2026-06-12.md | 83 + ...acetagvalues-functioncounter-2026-06-11.md | 68 + ...produces-accept-double-fault-2026-06-02.md | 56 + ...ixture-package-path-mismatch-2026-06-25.md | 59 + ...-ambiguous-exception-handler-2026-06-02.md | 69 + ...ortfolio-flyway-out-of-order-2026-06-23.md | 60 + ...2-resource-server-dependency-2026-05-27.md | 22 + ...lio-tomcat-port-in-use-check-2026-07-03.md | 78 + ...2-resource-server-dependency-2026-05-27.md | 77 + ...uild-verification-boundaries-2026-06-21.md | 74 + ...d-reaper-wrong-config-prefix-2026-06-09.md | 42 + ...jre-random-generator-missing-2026-06-24.md | 69 + ...ctor-breaks-webmvctest-slice-2026-06-14.md | 66 + ...ng3-bom-downgrade-noclassdef-2026-06-20.md | 74 + ...four-jackson-three-migration-2026-06-30.md | 296 + ...uctor-no-default-constructor-2026-06-12.md | 95 + ...-test-inner-config-collision-2026-06-17.md | 130 + ...ultimodule-overlap-collision-2026-06-23.md | 96 + ...-config-vs-autoconfiguration-2026-06-17.md | 75 + ...factory-method-not-processed-2026-06-11.md | 67 + ...ftersingletons-null-template-2026-06-13.md | 100 + ...a-flyway-circular-dependency-2026-06-23.md | 116 + ...ng-jpa-postgres-lob-oid-cast-2026-06-23.md | 68 + ...-suppression-spotless-format-2026-07-03.md | 74 + ...text-shared-datasource-close-2026-06-11.md | 49 + ...ockford-u-self-inconsistency-2026-06-01.md | 62 + ...constructor-dep-breaks-slice-2026-06-14.md | 72 + ...figuration-context-pollution-2026-06-01.md | 78 + ...-enum-placeholder-no-default-2026-06-20.md | 67 + .../project-notes/invest-money-flow-system.md | 251 + ...feature-keycloak-account-linking-spa-ux.md | 276 + ...e-keycloak-account-linking-sub-vs-email.md | 331 + ...ture-keycloak-bff-csrf-samesite-defense.md | 166 + ...eature-keycloak-bff-oauth2login-session.md | 166 + .../feature-keycloak-bff-vs-spa-direct.md | 324 + .../feature-keycloak-docker-compose-stack.md | 337 + ...loak-edge-forwardauth-google-federation.md | 378 + ...ure-keycloak-edge-forwardauth-no-google.md | 372 + ...ure-keycloak-federation-spa-zero-change.md | 238 + ...eature-keycloak-first-broker-login-flow.md | 311 + ...e-keycloak-four-pattern-tradeoff-matrix.md | 231 + ...keycloak-google-claim-attribute-mapping.md | 291 + ...ure-keycloak-google-redirect-uri-policy.md | 312 + ...eature-keycloak-header-spoofing-defense.md | 311 + ...-keycloak-https-termination-caddy-nginx.md | 333 + ...re-keycloak-idp-brokering-google-client.md | 307 + ...ture-keycloak-idp-mappers-claim-to-role.md | 196 + ...k-internal-spa-direct-google-federation.md | 513 + ...-keycloak-internal-spa-direct-no-google.md | 466 + ...re-keycloak-iss-claim-hostname-mismatch.md | 332 + ...keycloak-nginx-auth-request-integration.md | 355 + ...feature-keycloak-oauth2-proxy-oidc-flow.md | 328 + .../branch-notes/feature-keycloak-patterns.md | 309 + .../feature-keycloak-pkce-flow-stages.md | 235 + ...eature-keycloak-public-domain-tunneling.md | 264 + .../feature-keycloak-realm-client-export.md | 281 + ...re-keycloak-refresh-rotation-and-logout.md | 302 + ...feature-keycloak-refresh-token-rotation.md | 333 + .../feature-keycloak-reverse-proxy-headers.md | 341 + ...e-keycloak-single-ec2-google-federation.md | 399 + .../feature-keycloak-single-ec2-no-google.md | 391 + ...ure-keycloak-spa-token-storage-tradeoff.md | 306 + ...e-keycloak-spring-rs-audience-validator.md | 320 + ...feature-keycloak-spring-rs-role-mapping.md | 263 + .../feature-keycloak-three-leg-trust-chain.md | 272 + ...eycloak-traefik-forwardauth-alternative.md | 284 + .../feature-keycloak-vanilla-js-spa-pkce.md | 305 + .../keycloak-patterns-overview.md | 934 ++ .../llm-wiki-server-migration.md | 568 ++ .../experiment-nplus1-feed-api-replay.md | 307 + .../experiment-nplus1-highlight-feed.md | 378 + .../project-notes/nplus1-presentation-prep.md | 282 + .../project-notes/project-infra-overview.md | 196 + vault/20-evidence/.gitkeep | 1 + ...pter-togglz-ff4j-feature-toggle-library.md | 117 + .../api-versioning-github-rest-date-header.md | 111 + .../api-versioning-stripe-date-based.md | 106 + ...unen-hexagonal-architecture-spring-boot.md | 80 + .../company-tech-blogs/aws-iam-arn-format.md | 104 + ...ework-transactionmanager-spring-adapter.md | 99 + .../brandur-stripe-idempotency-keys.md | 106 + ...t-lombok-allowlist-direct-transactional.md | 168 + ...ache-woowahan-after-commit-invalidation.md | 103 + ...ci-flaky-test-quarantine-spotify-google.md | 111 + ...launchdarkly-feature-flag-best-practice.md | 124 + ...tainer-woowahan-spring-native-tradeoffs.md | 93 + ...an-architecture-read-path-bypass-wakita.md | 87 + .../curity-bff-pattern-spa.md | 102 + ...urity-oauth2-scope-vs-permission-naming.md | 77 + ...tom-transaction-interceptor-catnipcoder.md | 108 + ...actice-software-developers-redgreencode.md | 101 + ...omain-event-sourcing-vs-cqrs-greg-young.md | 137 + .../domain-woowahan-ddd-aggregate-techblog.md | 118 + ...-architecture-ddd-hexagonal-cqrs-hgraca.md | 85 + ...-sahibinden-package-by-layer-vs-feature.md | 101 + .../file-clamav-icap-gateway-scan.md | 118 + .../github-api-error-format.md | 135 + .../github-graphql-global-node-id.md | 103 + ...al-reflectoring-transactional-placement.md | 105 + .../hexagonal-woowahan-techblog-2023.md | 115 + .../idempotency-brandur-stripe-postgres.md | 119 + .../idempotency-redis-vs-db-storage.md | 123 + .../idempotency-toss-payments-techblog.md | 114 + ...-unknown-kid-refresh-rate-limit-pattern.md | 87 + .../keycloak-google-login-codemancers.md | 97 + ...eycloak-jwt-role-extraction-betweendata.md | 91 + ...ayer-first-kamilmazurek-github-template.md | 107 + ...ibe-advisory-lock-distributed-consensus.md | 91 + ...c-toss-payments-alert-severity-techblog.md | 114 + ...ometer-context-propagation-line-be-hase.md | 84 + ...h-arawn-github-modular-monoliths-spring.md | 103 + .../modulith-kakaobank-techblog-2025.md | 95 + .../multitenancy-atlassian-tenant-context.md | 114 + .../multitenancy-auth0-tenant-resolution.md | 111 + .../multitenancy-hybrid-pooled-siloed-mix.md | 125 + ...itenancy-stripe-citus-schema-per-tenant.md | 118 + ...titenancy-subdomain-resolution-patterns.md | 126 + ...udum-cqrs-separate-read-store-evolution.md | 85 + .../onion-allegro-tech-blog-2023.md | 100 + ...und-stripe-rate-limit-retry-engineering.md | 103 + .../outbox-confluent-kafka-connect-smt.md | 120 + .../outbox-netflix-domain-events-cdc.md | 119 + .../outbox-wix-engineering-debezium.md | 125 + .../outbox-woowahan-techblog-pattern.md | 117 + .../percona-uuid-storage-mysql.md | 136 + .../planetscale-nanoid-api.md | 106 + ...stgresql-slow-query-logging-crunchydata.md | 80 + ...udonymization-hmac-vs-tokenization-iapp.md | 106 + ...-tx-hibernate-optimization-vladmihalcea.md | 84 + ...e-service-experience-woowahan-websocket.md | 91 + ...etry-aws-exponential-backoff-and-jitter.md | 89 + ...unbook-atlassian-gitops-runbook-as-code.md | 103 + .../runbook-woowahan-incident-techblog.md | 101 + ...h-datadog-engineering-graceful-shutdown.md | 104 + ...affolding-backstage-golden-path-spotify.md | 115 + ...lue-structured-concurrency-softwaremill.md | 84 + ...s-1password-developer-secret-references.md | 108 + .../security-toss-actuator-healthcheck.md | 102 + .../security-woowahan-actuator-safe-usage.md | 102 + .../company-tech-blogs/segment-ksuid.md | 102 + ...senior-engineer-competency-mubin-shaikh.md | 113 + .../skillable-hands-on-lab-structure.md | 93 + ...y-datasource-proxy-spring-boot-galovics.md | 72 + .../snowflake-twitter-id.md | 108 + ...erated-exemption-and-violations-as-data.md | 173 + .../sse-realtime-notification-woowahan.md | 98 + .../company-tech-blogs/stripe-error-format.md | 128 + .../test-pyramid-vs-trophy-kent-dodds.md | 97 + ...en-hibernate-timestamp-clock-limitation.md | 85 + .../threadlocal-capture-restore-att-israel.md | 85 + .../toss-payments-error-format.md | 140 + .../tracing-datadog-apm-vs-opentelemetry.md | 112 + ...ransaction-port-clean-ddd-spring-medium.md | 110 + ...action-port-vassilis-soum-github-readme.md | 102 + ...alcea-postgresql-audit-logging-triggers.md | 82 + .../woowahan-hexagonal-multimodule.md | 110 + ...-06-05-passive-diversification-behavior.md | 87 + ...-06-05-stoploss-takeprofit-tax-accounts.md | 78 + ...6-08-broad-equity-etf-100man-candidates.md | 112 + ...-06-08-isa-vs-general-account-no-income.md | 111 + ...6-08-korean-broad-etf-ticker-comparison.md | 86 + ...uator-endpoint-exposure-spring-official.md | 104 + .../actuator-istio-sidecar-management-alt.md | 115 + ...ctuator-management-port-spring-official.md | 111 + .../adapter-java-spi-serviceloader.md | 108 + ...r-spring-boot-autoconfig-custom-starter.md | 119 + .../api-versioning-google-aip-180.md | 127 + .../arch-acl-microsoft-pattern.md | 98 + .../arch-clean-architecture-uncle-bob.md | 104 + .../official-docs/arch-hexagonal-cockburn.md | 104 + ...hunit-annotation-as-registry-evaluation.md | 137 + ...conditional-on-property-3-layer-pattern.md | 152 + .../official-docs/archunit-user-guide.md | 104 + .../at-transactional-spring-official.md | 103 + .../official-docs/aws-acm-managed-renewal.md | 130 + ...get-security-group-restriction-official.md | 90 + .../aws-builders-retry-jitter.md | 95 + ...nt-origin-shared-secret-header-official.md | 84 + ...google-iam-permission-naming-convention.md | 104 + ...aws-security-group-referencing-official.md | 80 + .../baggage-otel-baggage-api-spec.md | 80 + .../official-docs/baggage-w3c-baggage-spec.md | 86 + .../cache-aside-vs-write-through-aws.md | 112 + ...cache-caffeine-asyncloadingcache-readme.md | 116 + .../cache-redisson-rlock-vs-setnx.md | 121 + .../caddy-automatic-https-docs.md | 108 + .../calver-spec-calver-official.md | 83 + .../official-docs/certbot-user-guide.md | 92 + .../checkstyle-google-style-reference.md | 93 + ...ird-party-cookie-policy-google-official.md | 99 + .../ci-github-actions-vs-gitlab-comparison.md | 107 + .../ci-openapi-snapshot-diff-tooling.md | 108 + .../cloudevents-spec-required-attributes.md | 94 + .../cloudflare-tunnel-routing-official.md | 101 + .../compat-rfc-8594-sunset-header.md | 96 + .../config-12-factor-app-config.md | 105 + ...g-aws-appconfig-feature-flag-deployment.md | 111 + ...-spring-boot-externalized-configuration.md | 92 + ...fig-spring-cloud-config-server-official.md | 106 + ...pring-cloud-kubernetes-configmap-reload.md | 109 + .../container-alpine-java-musl-tradeoffs.md | 108 + .../container-distroless-google-github.md | 109 + ...tainer-graalvm-native-image-spring-boot.md | 116 + ...tainer-stdout-logging-12factor-official.md | 91 + ...gn-keyless-identity-verification-policy.md | 106 + .../official-docs/cqrs-fowler-bliki.md | 99 + .../cqrs-pattern-azure-architecture-center.md | 97 + .../official-docs/crockford-base32-spec.md | 94 + vault/20-evidence/official-docs/cuid2-spec.md | 105 + ...asource-micrometer-observation-official.md | 92 + .../datasource-proxy-slow-query-official.md | 93 + ...ndabot-security-updates-gradle-official.md | 95 + ...ependabot-supported-ecosystems-official.md | 92 + .../docker-compose-depends-on-healthcheck.md | 110 + ...compose-networking-extra-hosts-official.md | 85 + ...ker-engine-20-10-release-notes-official.md | 84 + .../docker-host-network-driver-official.md | 86 + ...-port-publishing-loopback-bind-official.md | 81 + .../official-docs/domain-event-fowler-eaa.md | 89 + .../domain-fowler-anemic-vs-rich-model.md | 114 + .../domain-vaughn-vernon-aggregate-root.md | 110 + ...dual-write-antipattern-microservices-io.md | 121 + .../dx-devcontainer-spring-boot.md | 113 + .../dx-mise-asdf-tool-versioning.md | 122 + .../dx-testcontainers-java-best-practices.md | 107 + ...-awslogs-stdout-cloudwatch-aws-official.md | 89 + .../errorprone-gradle-plugin-readme.md | 89 + ...ent-sourcing-vs-outbox-microservices-io.md | 124 + ...t-uncle-bob-screaming-architecture-2011.md | 112 + .../official-docs/fetch-spec-cors.md | 108 + .../file-s3-presigned-url-upload.md | 113 + .../file-tus-resumable-upload-protocol.md | 110 + .../official-docs/find-sec-bugs-official.md | 87 + .../functional-tx-arrow-kt-resource-docs.md | 121 + ...ptographic-erasure-envelope-key-pattern.md | 159 + .../github-dependency-review-action.md | 85 + .../official-docs/github-webhook-signature.md | 82 + .../google-aip-122-resource-names.md | 113 + .../google-aip-127-http-transcoding.md | 30 + .../google-aip-132-list-method.md | 125 + .../google-aip-136-custom-methods.md | 119 + .../google-aip-148-standard-fields.md | 101 + .../google-aip-151-long-running-operations.md | 123 + .../google-aip-158-pagination.md | 107 + .../official-docs/google-aip-160-filtering.md | 137 + .../google-aip-185-resource-versioning.md | 105 + .../google-aip-233-batch-create.md | 129 + .../official-docs/google-antigravity-hooks.md | 59 + .../official-docs/google-api-error-format.md | 137 + .../google-java-format-readme.md | 83 + ...pp-verification-state-overview-official.md | 95 + ...ogle-oauth-manage-app-audience-official.md | 94 + ...auth2-client-application-types-official.md | 82 + ...olicies-environment-separation-official.md | 85 + ...oauth2-redirect-uri-validation-official.md | 104 + .../google-oauth2-web-server-flow-official.md | 82 + .../google-oidc-discovery-spec.md | 139 + .../google-openid-connect-oidc.md | 103 + .../google-sre-workbook-on-call-monitoring.md | 103 + .../governance-archunit-official.md | 96 + ...adle-java-library-api-vs-implementation.md | 85 + ...eproducible-archives-working-with-files.md | 93 + .../official-docs/graphql-errors-spec.md | 129 + .../hexagonal-cockburn-wikipedia-summary.md | 108 + .../hexagonal-thombergs-buckpal-github.md | 110 + .../hibernate-slow-query-log-official.md | 78 + .../iana-media-types-registry.md | 108 + .../idempotency-aws-lambda-powertools.md | 118 + .../official-docs/idempotency-ietf-draft.md | 109 + .../idempotency-no-api-level-github-rest.md | 102 + .../official-docs/idempotency-paypal-docs.md | 107 + .../official-docs/idempotency-square-api.md | 109 + .../idempotency-stripe-api-ref.md | 116 + .../istio-mtls-cert-rotation-official.md | 86 + .../official-docs/jdk-files-createtempfile.md | 98 + .../jdk21-threadpoolexecutor-javadoc.md | 88 + .../official-docs/json-api-errors-spec.md | 126 + .../jsonapi-pagination-format.md | 97 + ...it5-conditional-env-variable-user-guide.md | 91 + ...ks-keycloak-key-rotation-active-passive.md | 94 + ...ose-jwksourcebuilder-spring-integration.md | 103 + ...lication-security-checklist-readonly-fs.md | 83 + .../k8s-configure-probes-task-page.md | 109 + ...ogging-architecture-kubernetes-official.md | 96 + .../k8s-network-policy-official.md | 96 + .../k8s-pod-lifecycle-probes-concept.md | 117 + .../k8s-pod-security-standards-restricted.md | 85 + ...cloak-2500-hostname-v2-release-official.md | 90 + ...cloak-2600-hostname-v1-removed-official.md | 76 + ...t-console-unlink-lockout-guard-official.md | 93 + ...thorization-services-realm-client-roles.md | 115 + ...ycloak-client-initiated-account-linking.md | 91 + ...client-pkce-method-enforcement-official.md | 89 + .../keycloak-configuring-database.md | 102 + .../keycloak-first-broker-login-flow.md | 120 + ...er-login-verify-authenticators-official.md | 107 + .../keycloak-first-login-flow.md | 101 + .../keycloak-getting-started-docker.md | 119 + .../keycloak-google-idp-setup.md | 103 + .../official-docs/keycloak-health-checks.md | 91 + .../keycloak-hostname-configuration.md | 132 + .../keycloak-identity-broker-spi.md | 92 + ...ak-identity-brokering-overview-official.md | 107 + .../keycloak-identity-provider-mappers.md | 126 + ...rovider-redirector-default-idp-official.md | 91 + ...ak-identity-provider-sync-mode-official.md | 90 + ...-identity-provider-trust-email-official.md | 85 + ...-idp-hide-on-login-page-toggle-official.md | 84 + ...loak-idp-hint-client-suggested-official.md | 85 + .../keycloak-import-export-realms.md | 82 + .../keycloak-oidc-logout-endpoint-official.md | 108 + ...esh-token-rotation-reuse-admin-official.md | 102 + ...efresh-token-rotation-sessions-official.md | 115 + .../keycloak-reverseproxy-official.md | 107 + ...eycloak-securing-apps-overview-official.md | 94 + .../keycloak-server-containers-docker.md | 128 + ...tes-exit-code-observability-termination.md | 114 + .../kubernetes-pod-lifecycle-termination.md | 83 + ...baeldung-clean-architecture-spring-boot.md | 96 + .../lock-postgres-advisory-locks.md | 108 + ...ck-shedlock-issue-899-non-scheduler-use.md | 91 + .../official-docs/lock-shedlock-readme.md | 88 + .../lock-spring-integration-lock-registry.md | 88 + .../log-ecs-schema-elastic-official.md | 108 + ...logback-mask-pattern-converter-official.md | 100 + .../log-otel-log-data-model-spec.md | 109 + .../lombok-builder-data-features-official.md | 88 + .../official-docs/lychee-link-checker.md | 102 + ...mapstruct-generated-annotation-official.md | 85 + ...-google-ewaschuk-philosophy-on-alerting.md | 86 + .../metric-google-sre-slo-burn-rate.md | 110 + .../metric-google-sre-workbook-on-call.md | 81 + ...crometer-high-cardinality-tags-detector.md | 96 + ...icrometer-histogram-percentile-concepts.md | 98 + ...c-micrometer-naming-convention-official.md | 97 + .../metric-otel-metrics-data-model-spec.md | 118 + ...theus-histograms-vs-summaries-practices.md | 88 + ...etheus-label-cardinality-best-practices.md | 84 + ...micrometer-context-propagation-official.md | 109 + ...opagation-purpose-thread-local-accessor.md | 103 + .../microservices-io-transactional-outbox.md | 103 + .../migration-atlas-schema-as-code.md | 111 + ...ion-flyway-official-concepts-and-repair.md | 124 + ...igration-k8s-init-container-job-pattern.md | 130 + ...n-liquibase-official-changelog-xml-yaml.md | 117 + .../modulith-spring-official-doc.md | 109 + ...cy-aws-saas-tenant-isolation-whitepaper.md | 115 + ...ultitenancy-azure-architecture-patterns.md | 119 + .../multitenancy-hibernate-user-guide.md | 112 + .../multitenancy-microservices-io-pattern.md | 120 + ...l-innodb-transaction-isolation-official.md | 85 + .../20-evidence/official-docs/nanoid-spec.md | 109 + .../nginx-auth-request-module-official.md | 112 + .../nginx-client-max-body-size.md | 103 + ...-core-module-location-internal-official.md | 92 + .../ngrok-http-tunnel-official.md | 106 + .../official-docs/oauth-v2-1-draft-ietf.md | 112 + .../oauth2-browser-based-apps-ietf-draft.md | 95 + .../official-docs/oauth2-pkce-rfc-7636.md | 109 + ...oxy-behaviour-cookie-vs-bearer-official.md | 88 + ...h2-proxy-cookie-redirect-flags-official.md | 103 + .../oauth2-proxy-endpoints-official.md | 96 + ...oauth2-proxy-endpoints-signout-official.md | 97 + ...2-proxy-keycloak-oidc-provider-official.md | 101 + ...oauth2-proxy-nginx-integration-official.md | 144 + .../oauth2-proxy-overview-config-official.md | 107 + .../oauth2-proxy-session-storage-official.md | 105 + .../oauth2-token-revocation-rfc-7009.md | 86 + .../official-docs/oidc-client-ts-library.md | 155 + .../onion-palermo-original-2008.md | 110 + .../official-docs/openapi-spec-3-1-0.md | 112 + ...openid-connect-core-id-token-validation.md | 93 + .../openjdk-jdk-8196595-container-support.md | 92 + ...ntelemetry-http-semconv-migration-guide.md | 81 + ...opentelemetry-versioning-stability-spec.md | 88 + .../otel-exceptions-semantic-conventions.md | 98 + .../outbound-openfeign-declarative-client.md | 109 + .../outbound-resilience4j-vs-spring-retry.md | 118 + .../outbound-spring-restclient-baseline.md | 110 + ...outbound-webclient-vs-restclient-spring.md | 118 + .../outbox-debezium-official-docs.md | 122 + .../outbox-skip-locked-microservices-io.md | 127 + .../owasp-authz-permission-model-abac-rbac.md | 96 + ...asp-content-security-policy-cheat-sheet.md | 98 + .../owasp-file-upload-cheat-sheet.md | 101 + .../official-docs/owasp-hsts-cheat-sheet.md | 104 + .../owasp-html5-storage-xss-spa.md | 99 + .../owasp-logging-cheat-sheet.md | 101 + .../official-docs/owasp-path-traversal.md | 103 + .../official-docs/owasp-ssrf-prevention.md | 79 + .../p6spy-configuration-official.md | 92 + .../official-docs/patch-json-merge-rfc7396.md | 100 + ...ersistence-hikaricp-configuration-knobs.md | 147 + .../persistence-hikaricp-pool-sizing-wiki.md | 108 + ...osiv-antipattern-hibernate-vladmihalcea.md | 101 + .../persistence-r2dbc-reactive-spring.md | 104 + ...ce-spring-dataaccessexception-hierarchy.md | 103 + ...postgres-transaction-isolation-official.md | 98 + .../postgresql-slow-query-log-official.md | 95 + ...acy-cryptographic-erasure-nist-sp800-88.md | 99 + .../privacy-gdpr-article-25-design.md | 103 + .../official-docs/problem-detail-rfc-7807.md | 129 + .../prometheus-alertmanager-silences.md | 101 + ...obuf-reserved-vs-json-openapi-extension.md | 145 + .../proxy-pass-request-body-nginx-official.md | 83 + .../official-docs/react-router-official.md | 90 + .../react-ui-library-official.md | 87 + ...dhat-openjdk-container-awareness-java17.md | 90 + .../official-docs/registry-adr-official.md | 97 + .../renovate-gradle-manager-official.md | 87 + ...te-vulnerability-alerts-gradle-official.md | 106 + .../reproducible-builds-org-jvm-guide.md | 93 + .../resilience4j-micrometer-module.md | 110 + .../retry-aws-well-architected-rel05-bp03.md | 85 + ...ry-spring-retry-readme-backoff-defaults.md | 91 + .../official-docs/rfc3339-datetime-utc.md | 109 + .../rfc3986-uri-generic-syntax.md | 94 + .../official-docs/rfc6455-websocket.md | 95 + .../rfc8996-tls10-tls11-deprecation.md | 109 + .../official-docs/rfc9110-http-semantics.md | 170 + .../official-docs/rfc9111-http-caching.md | 107 + .../rfc9112-http-1-1-chunked-transfer.md | 106 + .../rfc9421-http-message-signatures.md | 88 + .../rfc9457-problem-details-http-apis.md | 88 + .../20-evidence/official-docs/rfc9562-uuid.md | 97 + ...runbook-pagerduty-incident-response-doc.md | 121 + .../runtime-health-istio-mesh-health-check.md | 103 + .../runtime-health-k8s-probes-official.md | 116 + .../runtime-health-spring-actuator-groups.md | 119 + .../runtime-spring-boot-virtual-threads.md | 116 + ...ample-microservices-spring-cloud-github.md | 104 + .../sample-realworld-gothinkster-github.md | 103 + .../sample-spring-petclinic-github.md | 97 + .../scaffolding-cookiecutter-official.md | 95 + .../scaffolding-degit-svelte-github.md | 95 + .../scaffolding-github-template-repository.md | 95 + .../scaffolding-spring-initializr.md | 97 + .../schema-avro-evolution-rules.md | 100 + ...ema-bigdecimal-money-serialization-java.md | 102 + ...ema-jackson-polymorphic-deserialization.md | 125 + .../schema-jackson-unknown-field-handling.md | 98 + .../schema-protobuf-vs-json-evolution.md | 106 + .../scoped-value-jep-446-506-openjdk.md | 90 + .../scorecard-aws-well-architected.md | 106 + .../scorecard-cis-benchmarks-slsa.md | 130 + .../scorecard-opentelemetry-maturity.md | 104 + .../secrets-aws-secrets-manager-rotation.md | 115 + ...ts-k8s-secret-external-secrets-operator.md | 119 + ...secrets-vault-dynamic-secrets-hashicorp.md | 110 + ...security-authorization-cheatsheet-owasp.md | 108 + .../security-aws-sigv4-hmac-signing.md | 106 + .../security-jwt-rfc-7519-validation.md | 107 + .../official-docs/security-mtls-rfc-8705.md | 108 + .../security-oauth2-pkce-rfc-8252.md | 102 + .../security-opa-policy-engine-official.md | 122 + ...ring-jwt-timestamp-validator-clock-skew.md | 87 + .../semver-2-0-0-spec-semver-official.md | 84 + ...o-third-party-cookies-keycloak-official.md | 89 + .../official-docs/skip-locked-mysql-docs.md | 117 + .../skip-locked-postgres-docs.md | 111 + .../slsa-v1-provenance-schema.md | 142 + .../sonarqube-server-versus-cloud.md | 78 + .../spotbugs-gradle-plugin-docs.md | 90 + .../spotless-gradle-plugin-readme.md | 86 + ...oot-exit-code-generator-startup-failure.md | 80 + ...spring-boot-graceful-shutdown-reference.md | 87 + .../spring-boot-multipart-reference.md | 131 + .../spring-boot-structuring-your-code.md | 86 + ...oot-task-execution-scheduling-reference.md | 86 + ...-slices-webmvctest-datajpatest-official.md | 84 + .../spring-data-jpa-auditing-official.md | 88 + ...spring-data-jpa-enable-jpa-auditing-api.md | 85 + ...ng-data-jpa-projections-spring-official.md | 90 + ...ta-jpa-transactionality-spring-official.md | 77 + .../spring-data-pageable-defaults.md | 126 + ...-executor-configuration-support-javadoc.md | 85 + ...lity-context-propagating-task-decorator.md | 80 + ...ework-test-enabledif-jupiter-annotation.md | 85 + ...ramework-threadpooltaskexecutor-javadoc.md | 83 + .../spring-mvc-async-streaming.md | 93 + .../spring-mvc-rest-exception-handling.md | 92 + .../official-docs/spring-problem-detail.md | 117 + .../spring-restclient-builder-reference.md | 106 + ...ing-security-authorization-architecture.md | 105 + ...security-authorization-defense-in-depth.md | 78 + ...spring-security-authorize-http-requests.md | 82 + ...cy-delegating-security-context-executor.md | 83 + .../spring-security-method-security.md | 94 + ...ty-nested-authorities-claim-issue-15201.md | 81 + .../spring-security-resource-server-jwt.md | 169 + .../spring-smartlifecycle-reference.md | 123 + .../spring-streaming-response-body.md | 115 + ...saction-synchronization-manager-javadoc.md | 86 + .../spring-transactional-event-listener.md | 109 + .../spring-tx-management-reference.md | 119 + ...ropagation-required-new-nested-official.md | 88 + .../stripe-resource-id-convention.md | 106 + .../official-docs/stripe-webhook-signature.md | 100 + ...sunset-deprecation-headers-paired-usage.md | 150 + .../supply-chain-cosign-keyless-sigstore.md | 122 + ...hain-gradle-vs-maven-dependency-locking.md | 123 + .../supply-chain-slsa-provenance-framework.md | 106 + .../svix-webhook-best-practices.md | 86 + .../sysexits-bsd-exit-code-convention.md | 96 + .../tailwind-css-utility-first-official.md | 88 + .../tanstack-query-server-state-official.md | 91 + .../test-taxonomy-practical-pyramid-fowler.md | 109 + .../test-taxonomy-testcontainers-official.md | 101 + ...-cookie-blocking-safari-webkit-official.md | 88 + ...readlocal-virtual-threads-java21-oracle.md | 87 + .../trace-context-w3c-recommendation.md | 90 + .../tracing-b3-propagation-zipkin-spec.md | 106 + ...ing-micrometer-observation-introduction.md | 81 + ...tracing-otel-sampling-tail-vs-head-spec.md | 102 + .../tracing-otel-trace-api-spec.md | 88 + ...pring-boot-3-actuator-tracing-reference.md | 95 + .../tracing-w3c-trace-context-spec.md | 119 + ...traefik-forwardauth-middleware-official.md | 96 + .../traefik-hub-oidc-middleware-official.md | 91 + ...community-plugin-lukaszraczylo-official.md | 104 + .../transaction-template-spring-official.md | 105 + ...tional-outbox-aws-prescriptive-guidance.md | 98 + .../trivy-action-github-actions.md | 106 + .../trivy-filtering-suppression-policy.md | 85 + .../trivy-java-language-coverage.md | 85 + .../trivy-severity-exit-code-gating.md | 87 + vault/20-evidence/official-docs/ulid-spec.md | 109 + ...dation-jakarta-bean-validation-3.0-spec.md | 92 + ...ication-approvaltests-snapshot-official.md | 105 + .../verification-pact-cdc-official.md | 104 + ...fication-spring-cloud-contract-official.md | 103 + .../verification-spring-restdocs-official.md | 94 + .../official-docs/vite-build-tool-official.md | 85 + ...vuln-severity-cisa-kev-catalog-official.md | 102 + ...n-severity-cvss-v31-spec-first-official.md | 94 + .../whatwg-html-server-sent-events.md | 98 + .../zod-runtime-schema-validation-official.md | 91 + vault/30-knowledge/.gitkeep | 1 + .../concepts/api-error-envelope-design.md | 151 + .../concepts/api-evolution-and-schema.md | 177 + ...hunit-scope-classpath-vs-package-filter.md | 81 + .../boundary-validation-and-dto-mapping.md | 86 + .../30-knowledge/concepts/circuit-breaker.md | 64 + .../clean-architecture-package-layout.md | 124 + .../concepts/config-and-adapter-templates.md | 96 + .../data-layer-persistence-cache-outbound.md | 128 + .../concepts/devops-ci-supply-chain-dx.md | 130 + .../concepts/distributed-tracing-baggage.md | 64 + .../concepts/fail-open-fail-closed.md | 61 + .../concepts/idempotency-key-design.md | 141 + vault/30-knowledge/concepts/idempotency.md | 60 + .../multi-tenancy-isolation-patterns.md | 142 + .../observability-log-metric-trace-runbook.md | 155 + vault/30-knowledge/concepts/outbox-pattern.md | 65 + .../concepts/privacy-file-domain-modeling.md | 116 + .../concepts/resource-identifier-format.md | 135 + .../runtime-container-health-migration.md | 158 + .../concepts/sample-fixture-and-adoption.md | 83 + .../security-baseline-jwt-actuator-secrets.md | 138 + ...ce-registry-verification-test-scorecard.md | 153 + .../concepts/spring-smart-lifecycle.md | 66 + .../concepts/streaming-response-patterns.md | 86 + .../transaction-boundary-abstraction.md | 172 + .../concepts/transactional-outbox-pattern.md | 112 + .../explainer/adapter-identifier.md | 18 + .../explainer/adapter-outbound.md | 923 ++ .../explainer/adapter-persistence.md | 18 + vault/30-knowledge/explainer/adapter-web.md | 18 + .../explainer/application-core.md | 18 + vault/30-knowledge/explainer/domain-core.md | 18 + .../images/outbound-adapter-architecture.png | Bin 0 -> 687915 bytes .../images/outbound-http-sequence.png | Bin 0 -> 620153 bytes .../30-knowledge/explainer/shared-contract.md | 18 + .../transaction-boundary-abstraction.md | 220 + .../invest-concepts/field-auto.md | 65 + .../invest-concepts/field-bigtech-ai.md | 56 + .../invest-concepts/field-bio-pharma.md | 65 + .../invest-concepts/field-bitcoin.md | 54 + .../invest-concepts/field-chem-refining.md | 66 + .../field-cosmetics-consumer.md | 65 + .../invest-concepts/field-defense.md | 64 + .../invest-concepts/field-dollar.md | 57 + .../invest-concepts/field-em-china.md | 55 + .../invest-concepts/field-entertainment.md | 65 + .../invest-concepts/field-financials.md | 65 + .../invest-concepts/field-game.md | 67 + .../invest-concepts/field-gold.md | 55 + .../field-internet-platform.md | 67 + .../invest-concepts/field-krw-rates.md | 55 + .../30-knowledge/invest-concepts/field-map.md | 63 + .../invest-concepts/field-nuclear-power.md | 64 + .../30-knowledge/invest-concepts/field-oil.md | 56 + .../invest-concepts/field-robotics.md | 65 + .../invest-concepts/field-rotation.md | 74 + .../field-secondary-battery.md | 67 + .../invest-concepts/field-semiconductors.md | 67 + .../invest-concepts/field-shipbuilding.md | 66 + .../invest-concepts/field-steel-materials.md | 65 + .../invest-concepts/field-telecom-utility.md | 66 + .../invest-concepts/field-us-equity.md | 59 + .../invest-concepts/field-us-rates.md | 58 + vault/30-knowledge/invest-plan/active-plan.md | 109 + .../30-knowledge/invest-strategy/strategy.md | 106 + vault/30-knowledge/invest/invest-hub.md | 50 + vault/30-knowledge/projects/ca-tmpl.md | 70 + .../ca-tmpl/api-error-envelope-design.md | 182 + .../ca-tmpl/api-evolution-and-schema.md | 225 + .../ca-tmpl/boundary-validation-mapping.md | 163 + .../clean-architecture-package-layout.md | 207 + .../ca-tmpl/config-and-adapter-templates.md | 127 + .../data-layer-persistence-cache-outbound.md | 255 + .../ca-tmpl/devops-ci-supply-chain-dx.md | 141 + .../ca-tmpl/idempotency-key-design.md | 121 + .../ca-tmpl/knowledge-capture-workflow.md | 75 + .../multi-tenancy-isolation-patterns.md | 125 + .../observability-log-metric-trace-runbook.md | 143 + .../ca-tmpl/privacy-file-domain-modeling.md | 134 + .../ca-tmpl/resource-identifier-format.md | 156 + .../runtime-container-health-migration.md | 149 + .../ca-tmpl/sample-fixture-and-adoption.md | 129 + .../security-baseline-jwt-actuator-secrets.md | 158 + ...ce-registry-verification-test-scorecard.md | 146 + .../ca-tmpl/streaming-response-support.md | 142 + .../transaction-boundary-abstraction.md | 142 + .../ca-tmpl/transactional-outbox-pattern.md | 143 + vault/40-publish/.gitkeep | 1 + ...nset-header-migration-window-2026-07-02.md | 81 + ...eturn-type-purity-query-port-2026-06-05.md | 87 + ...-typing-cve-2019-14379-block-2026-05-29.md | 101 + ...y-fixture-annotation-pattern-2026-06-02.md | 97 + ...t-violations-as-data-pattern-2026-05-28.md | 111 + ...-clean-architecture-skeleton-2026-07-02.md | 81 + ...on-mapper-responsibility-map-2026-07-02.md | 82 + ...d-router-fail-open-decorator-2026-07-02.md | 81 + ...ter-commit-stampede-contract-2026-07-02.md | 81 + ...e-wiring-vs-policy-ownership-2026-06-20.md | 88 + ...tecture-boundary-enforcement-2026-05-28.md | 121 + ...rchitecture-module-blueprint-2026-05-28.md | 127 + ...e-reference-project-adoption-2026-06-17.md | 86 + ...hema-owner-vs-row-owner-gate-2026-06-20.md | 91 + ...fication-suite-release-gates-2026-07-02.md | 81 + ...-first-java-release-pipeline-2026-06-21.md | 91 + ...-transaction-commit-boundary-2026-07-02.md | 81 + ...s-archunit-fitness-functions-2026-06-05.md | 101 + ...nv-example-drift-gate-gradle-2026-06-06.md | 101 + ...lean-architecture-onboarding-2026-06-25.md | 86 + ...age-local-bootstrap-contract-2026-06-24.md | 87 + ...orization-clean-architecture-2026-06-08.md | 94 + ...cy-security-gate-portability-2026-07-02.md | 82 + ...a21-static-analysis-baseline-2026-06-20.md | 92 + ...ob-constraints-startup-guard-2026-06-09.md | 101 + ...ion-layer-clean-architecture-2026-06-09.md | 101 + ...ance-rule-scoping-by-id-kind-2026-06-01.md | 81 + ...ion-strategy-virtual-threads-2026-07-02.md | 82 + ...nectexception-classification-2026-07-02.md | 81 + ...s-container-oomkill-exit-137-2026-07-02.md | 81 + ...cret-masking-json-vs-pattern-2026-06-14.md | 76 + ...fest-driven-agent-harness-policy-engine.md | 81 + ...resilience4j-functioncounter-2026-07-02.md | 81 + ...-lab-checkoutable-api-replay-2026-07-15.md | 105 + ...lope-meta-category-migration-2026-06-01.md | 90 + ...-metadata-clean-architecture-2026-07-02.md | 81 + ...n-knowledge-capture-workflow-2026-05-28.md | 113 + ...ty-archunit-fitness-function-2026-07-02.md | 82 + ...coverage-junit-contract-test-2026-07-02.md | 81 + ...t-fixture-clean-architecture-2026-06-10.md | 84 + ...xture-dual-mode-build-matrix-2026-06-25.md | 95 + ...e-port-restart-only-rotation-2026-07-02.md | 82 + ...tbox-per-aggregate-fifo-gate-2026-06-11.md | 90 + ...tor-health-probe-group-split-2026-07-02.md | 82 + ...executor-saturation-shutdown-2026-06-13.md | 101 + ...rd-multi-constructor-binding-2026-06-12.md | 127 + ...-serialization-contract-pins-2026-07-02.md | 81 + ...tartup-exit-code-propagation-2026-06-10.md | 115 + ...ty-optional-adapter-template-2026-06-09.md | 95 + ...r-transport-failure-envelope-2026-07-02.md | 82 + ...-filter-layer-error-envelope-2026-06-08.md | 93 + ...e-not-supported-archunit-ban-2026-07-02.md | 82 + ...axonomy-archunit-enforcement-2026-06-19.md | 93 + ...isolation-vendor-default-pin-2026-07-02.md | 82 + ...on-over-spring-transactional-2026-05-28.md | 127 + ...ssion-governance-static-gate-2026-06-20.md | 87 + ...ford-base32-excluded-letters-2026-06-01.md | 81 + ...ceparent-fork-activated-seam-2026-07-02.md | 82 + ...ull-jitter-dlq-observability-2026-07-02.md | 82 + ...ok-signature-replay-contract-2026-07-02.md | 84 + ...-egress-proxy-redirect-block-2026-07-02.md | 82 + ...pl-api-error-envelope-design-2026-07-02.md | 239 + ...mpl-api-evolution-and-schema-2026-07-02.md | 257 + ...-boundary-validation-mapping-2026-07-02.md | 255 + ...-architecture-package-layout-2026-07-02.md | 199 + ...config-and-adapter-templates-2026-07-02.md | 154 + ...r-persistence-cache-outbound-2026-07-02.md | 184 + ...pl-devops-ci-supply-chain-dx-2026-07-02.md | 143 + ...-tmpl-idempotency-key-design-2026-07-02.md | 160 + ...l-knowledge-capture-workflow-2026-07-02.md | 121 + ...i-tenancy-isolation-patterns-2026-07-02.md | 146 + ...ity-log-metric-trace-runbook-2026-07-02.md | 165 + ...privacy-file-domain-modeling-2026-07-02.md | 152 + ...l-resource-identifier-format-2026-07-02.md | 160 + ...e-container-health-migration-2026-07-02.md | 166 + ...-sample-fixture-and-adoption-2026-07-02.md | 158 + ...aseline-jwt-actuator-secrets-2026-07-02.md | 164 + ...-verification-test-scorecard-2026-07-02.md | 148 + ...l-streaming-response-support-2026-07-02.md | 144 + ...saction-boundary-abstraction-2026-07-02.md | 201 + ...transactional-outbox-pattern-2026-07-02.md | 177 + ...hunit-manual-importer-vs-analyzeclasses.md | 43 + .../archunit-static-analysis-limits.md | 101 + ...t-violations-as-data-pattern-2026-06-02.md | 32 + ...turation-context-propagation-2026-06-13.md | 53 + ...release-gate-fan-in-blocking-2026-06-20.md | 49 + ...clean-architecture-boundary-enforcement.md | 104 + ...chitecture-domain-onboarding-guardrails.md | 61 + ...lean-architecture-identifier-generation.md | 53 + ...tion-without-spring-coupling-2026-06-08.md | 41 + .../clean-architecture-module-blueprint.md | 107 + ...crown-one-query-vs-cqrs-lite-read-model.md | 61 + ...yncappender-drop-metric-test-2026-06-14.md | 42 + ...digest-first-supply-chain-release-gates.md | 64 + ...modeling-guardrails-archunit-2026-06-05.md | 46 + ...-linter-responsibility-split-2026-06-20.md | 49 + ...dle-sample-off-test-classpath-isolation.md | 33 + ...-rate-limit-design-tradeoffs-2026-06-09.md | 53 + ...grained-error-classification-2026-06-08.md | 46 + ...est-driven-multi-platform-agent-harness.md | 60 + ...tive-query-addscalar-runtime-validation.md | 62 + ...r-envelope-and-observability-foundation.md | 58 + ...r-3-layer-disabled-detection-2026-06-09.md | 48 + .../post-implementation-knowledge-capture.md | 102 + ...ain-contract-fixture-clean-architecture.md | 58 + .../shared-contract-and-sample-isolation.md | 98 + .../single-command-local-bootstrap.md | 58 + ...alization-lifecycle-circular-dependency.md | 56 + ...-fail-fast-config-validation-2026-06-06.md | 50 + ...ransaction-port-vs-spring-transactional.md | 109 + ...x-skip-locked-implementation-2026-06-11.md | 40 + ...sion-dual-control-governance-2026-06-20.md | 62 + .../publish-blog/api-error-envelope-blog.md | 209 + .../publish-blog/api-evolution-schema-blog.md | 201 + .../boundary-validation-mapping-blog.md | 193 + .../publish-blog/ci-supply-chain-blog.md | 138 + .../clean-architecture-package-layout-blog.md | 197 + ...a-layer-persistence-cache-outbound-blog.md | 196 + .../optional-adapter-config-contract-blog.md | 162 + .../topics-interview/clean-architecture.md | 334 + vault/50-journal/.gitkeep | 1 + vault/50-journal/daily-notes/2026-05-27.md | 142 + vault/50-journal/daily-notes/2026-05-28.md | 65 + vault/50-journal/daily-notes/2026-06-14.md | 55 + vault/50-journal/daily-notes/2026-06-30.md | 55 + vault/50-journal/daily-tasks/README.md | 265 + ...-archunit-controller-domain-return-rule.md | 236 + ...readiness-probe-db-disconnect-detection.md | 360 + vault/50-journal/invest-daily/2026-06-06.md | 63 + vault/50-journal/invest-daily/2026-06-08.md | 103 + vault/50-journal/invest-ledger/ledger.md | 50 + vault/90-archive/.gitkeep | 1 + ...feature-template-instantiation-contract.md | 217 + vault/README.md | 24 + ...pl-api-error-envelope-design-2026-07-02.md | 1 + ...mpl-api-evolution-and-schema-2026-07-02.md | 1 + ...-boundary-validation-mapping-2026-07-02.md | 1 + ...-architecture-package-layout-2026-07-02.md | 1 + ...config-and-adapter-templates-2026-07-02.md | 1 + ...r-persistence-cache-outbound-2026-07-02.md | 1 + ...pl-devops-ci-supply-chain-dx-2026-07-02.md | 1 + ...-tmpl-idempotency-key-design-2026-07-02.md | 1 + ...l-knowledge-capture-workflow-2026-07-02.md | 1 + ...i-tenancy-isolation-patterns-2026-07-02.md | 1 + ...ity-log-metric-trace-runbook-2026-07-02.md | 1 + ...privacy-file-domain-modeling-2026-07-02.md | 1 + ...l-resource-identifier-format-2026-07-02.md | 1 + ...e-container-health-migration-2026-07-02.md | 1 + ...-sample-fixture-and-adoption-2026-07-02.md | 1 + ...aseline-jwt-actuator-secrets-2026-07-02.md | 1 + ...-verification-test-scorecard-2026-07-02.md | 1 + ...l-streaming-response-support-2026-07-02.md | 1 + ...saction-boundary-abstraction-2026-07-02.md | 1 + ...transactional-outbox-pattern-2026-07-02.md | 1 + wiki/concepts/api-error-envelope-design.md | 1 + wiki/concepts/api-evolution-and-schema.md | 1 + ...hunit-scope-classpath-vs-package-filter.md | 1 + .../boundary-validation-and-dto-mapping.md | 1 + wiki/concepts/circuit-breaker.md | 1 + .../clean-architecture-package-layout.md | 1 + wiki/concepts/config-and-adapter-templates.md | 1 + .../data-layer-persistence-cache-outbound.md | 1 + wiki/concepts/devops-ci-supply-chain-dx.md | 1 + wiki/concepts/distributed-tracing-baggage.md | 1 + wiki/concepts/fail-open-fail-closed.md | 1 + wiki/concepts/idempotency-key-design.md | 1 + wiki/concepts/idempotency.md | 1 + .../multi-tenancy-isolation-patterns.md | 1 + .../observability-log-metric-trace-runbook.md | 1 + wiki/concepts/outbox-pattern.md | 1 + wiki/concepts/privacy-file-domain-modeling.md | 1 + wiki/concepts/resource-identifier-format.md | 1 + .../runtime-container-health-migration.md | 1 + wiki/concepts/sample-fixture-and-adoption.md | 1 + .../security-baseline-jwt-actuator-secrets.md | 1 + ...ce-registry-verification-test-scorecard.md | 1 + wiki/concepts/spring-smart-lifecycle.md | 1 + wiki/concepts/streaming-response-patterns.md | 1 + .../transaction-boundary-abstraction.md | 1 + wiki/concepts/transactional-outbox-pattern.md | 1 + wiki/explainer/adapter-identifier.md | 1 + wiki/explainer/adapter-outbound.md | 1 + wiki/explainer/adapter-persistence.md | 1 + wiki/explainer/adapter-web.md | 1 + wiki/explainer/application-core.md | 1 + wiki/explainer/domain-core.md | 1 + .../images/outbound-adapter-architecture.png | 1 + .../images/outbound-http-sequence.png | 1 + wiki/explainer/shared-contract.md | 1 + .../transaction-boundary-abstraction.md | 1 + wiki/invest-concepts/field-auto.md | 1 + wiki/invest-concepts/field-bigtech-ai.md | 1 + wiki/invest-concepts/field-bio-pharma.md | 1 + wiki/invest-concepts/field-bitcoin.md | 1 + wiki/invest-concepts/field-chem-refining.md | 1 + .../field-cosmetics-consumer.md | 1 + wiki/invest-concepts/field-defense.md | 1 + wiki/invest-concepts/field-dollar.md | 1 + wiki/invest-concepts/field-em-china.md | 1 + wiki/invest-concepts/field-entertainment.md | 1 + wiki/invest-concepts/field-financials.md | 1 + wiki/invest-concepts/field-game.md | 1 + wiki/invest-concepts/field-gold.md | 1 + .../field-internet-platform.md | 1 + wiki/invest-concepts/field-krw-rates.md | 1 + wiki/invest-concepts/field-map.md | 1 + wiki/invest-concepts/field-nuclear-power.md | 1 + wiki/invest-concepts/field-oil.md | 1 + wiki/invest-concepts/field-robotics.md | 1 + wiki/invest-concepts/field-rotation.md | 1 + .../field-secondary-battery.md | 1 + wiki/invest-concepts/field-semiconductors.md | 1 + wiki/invest-concepts/field-shipbuilding.md | 1 + wiki/invest-concepts/field-steel-materials.md | 1 + wiki/invest-concepts/field-telecom-utility.md | 1 + wiki/invest-concepts/field-us-equity.md | 1 + wiki/invest-concepts/field-us-rates.md | 1 + wiki/invest-plan/.gitkeep | 0 wiki/invest-plan/active-plan.md | 1 + wiki/invest-strategy/.gitkeep | 0 wiki/invest-strategy/strategy.md | 1 + wiki/invest/.gitkeep | 0 wiki/invest/invest-hub.md | 1 + wiki/invest/invest-hub/.gitkeep | 0 wiki/llm-wiki.md | 153 + wiki/log.md | 160 + wiki/projects/ca-tmpl.md | 1 + .../ca-tmpl/api-error-envelope-design.md | 1 + .../ca-tmpl/api-evolution-and-schema.md | 1 + .../ca-tmpl/boundary-validation-mapping.md | 1 + .../clean-architecture-package-layout.md | 1 + .../ca-tmpl/config-and-adapter-templates.md | 1 + .../data-layer-persistence-cache-outbound.md | 1 + .../ca-tmpl/devops-ci-supply-chain-dx.md | 1 + .../ca-tmpl/idempotency-key-design.md | 1 + .../ca-tmpl/knowledge-capture-workflow.md | 1 + .../multi-tenancy-isolation-patterns.md | 1 + .../observability-log-metric-trace-runbook.md | 1 + .../ca-tmpl/privacy-file-domain-modeling.md | 1 + .../ca-tmpl/resource-identifier-format.md | 1 + .../runtime-container-health-migration.md | 1 + .../ca-tmpl/sample-fixture-and-adoption.md | 1 + .../security-baseline-jwt-actuator-secrets.md | 1 + ...ce-registry-verification-test-scorecard.md | 1 + .../ca-tmpl/streaming-response-support.md | 1 + .../transaction-boundary-abstraction.md | 1 + .../ca-tmpl/transactional-outbox-pattern.md | 1 + wiki/publish-blog/api-error-envelope-blog.md | 1 + .../publish-blog/api-evolution-schema-blog.md | 1 + .../boundary-validation-mapping-blog.md | 1 + wiki/publish-blog/ci-supply-chain-blog.md | 1 + .../clean-architecture-package-layout-blog.md | 1 + ...a-layer-persistence-cache-outbound-blog.md | 1 + .../optional-adapter-config-contract-blog.md | 1 + wiki/topics-interview/clean-architecture.md | 1 + 2436 files changed, 194486 insertions(+), 1 deletion(-) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 cspell.json create mode 100644 docs/superpowers/README.md create mode 100644 docs/superpowers/notes/2026-06-04-phase1-empirical-format-check.md create mode 100644 docs/superpowers/notes/2026-06-04-phase2-antigravity-hook-coverage.md create mode 100644 docs/superpowers/notes/2026-06-04-phase2-codex-hook-schema.md create mode 100644 docs/superpowers/plans/2026-06-01-branch-depth-gate.md create mode 100644 docs/superpowers/plans/2026-06-02-obsidian-link-validation-hardening.md create mode 100644 docs/superpowers/plans/2026-06-04-three-platform-sync-phase0-engine-agents.md create mode 100644 docs/superpowers/plans/2026-06-04-three-platform-sync-phase1-commands.md create mode 100644 docs/superpowers/plans/2026-06-04-three-platform-sync-phase2-hooks-agentsmd.md create mode 100644 docs/superpowers/plans/2026-06-04-wiki-project-template-source-type-split.md create mode 100644 docs/superpowers/plans/2026-06-05-investment-wiki-pipeline.md create mode 100644 docs/superpowers/plans/2026-06-05-project-note-pipeline.md create mode 100644 docs/superpowers/plans/2026-06-06-spec-a-deterministic-backbone-gate.md create mode 100644 docs/superpowers/plans/2026-06-06-spec-b-judge-verdict-schema-and-quorum.md create mode 100644 docs/superpowers/plans/2026-06-06-spec-c-funnel-stats-no-silent-truncation.md create mode 100644 docs/superpowers/plans/2026-06-06-spec-d-research-fanout-workflow.md create mode 100644 docs/superpowers/plans/2026-06-08-invest-field-map.md create mode 100644 docs/superpowers/plans/2026-06-08-invest-system-buildout.md create mode 100644 docs/superpowers/plans/2026-06-09-deep-research-codex-antigravity-port.md create mode 100644 docs/superpowers/plans/2026-07-14-harness-correctness-sweep.md create mode 100644 docs/superpowers/specs/2026-06-01-branch-depth-gate-design.md create mode 100644 docs/superpowers/specs/2026-06-01-operational-error-observability-foundation-reinforcement-design.md create mode 100644 docs/superpowers/specs/2026-06-01-wiki-structure-lint-design.md create mode 100644 docs/superpowers/specs/2026-06-02-branch-spec-assembly-pipeline-design.md create mode 100644 docs/superpowers/specs/2026-06-02-coverage-gate-design.md create mode 100644 docs/superpowers/specs/2026-06-02-korean-prose-style-design.md create mode 100644 docs/superpowers/specs/2026-06-02-obsidian-link-validation-hardening-design.md create mode 100644 docs/superpowers/specs/2026-06-02-validation-strengthening-design.md create mode 100644 docs/superpowers/specs/2026-06-04-ca-tmpl-optimization-per-file-findings.md create mode 100644 docs/superpowers/specs/2026-06-04-ca-tmpl-optimization-report.md create mode 100644 docs/superpowers/specs/2026-06-04-three-platform-workflow-sync-design.md create mode 100644 docs/superpowers/specs/2026-06-04-wiki-project-template-source-type-split-design.md create mode 100644 docs/superpowers/specs/2026-06-05-investment-wiki-pipeline-design.md create mode 100644 docs/superpowers/specs/2026-06-05-project-note-pipeline-design.md create mode 100644 docs/superpowers/specs/2026-06-06-harness-audit-report.md create mode 100644 docs/superpowers/specs/2026-06-06-spec-a-deterministic-backbone-gate-design.md create mode 100644 docs/superpowers/specs/2026-06-06-spec-b-judge-verdict-schema-and-quorum-design.md create mode 100644 docs/superpowers/specs/2026-06-06-spec-c-funnel-stats-no-silent-truncation-design.md create mode 100644 docs/superpowers/specs/2026-06-06-spec-d-research-fanout-workflow-design.md create mode 100644 docs/superpowers/specs/2026-06-08-invest-field-map-design.md create mode 100644 docs/superpowers/specs/2026-06-08-spec-e-antigravity-hook-port-design.md create mode 100644 docs/superpowers/specs/2026-06-08-spec-f-invest-pipeline-hardening-design.md create mode 100644 docs/superpowers/specs/2026-06-09-deep-research-codex-antigravity-port-design.md create mode 100644 docs/superpowers/specs/2026-06-10-claude-harness-audit-report.md create mode 100644 docs/superpowers/specs/2026-06-10-consistency-layer-design.md create mode 100644 docs/superpowers/specs/2026-06-10-tiered-extraction-design.md create mode 100644 docs/superpowers/specs/2026-07-14-harness-correctness-sweep-design.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review-adversarial-review.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review-controller-verification.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review-report.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/adversarial-review.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/diagram-review.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/evidence-matrix.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/lanes/lane-01-target-review.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/lanes/lane-02-benchmark-patterns.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/per-file-findings.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/priority-recommendations.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/process/implementation_plan.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/process/pre-review-source.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/process/task.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/process/walkthrough.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/sed-proofs.md create mode 100644 docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/unresolved-risk-register.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency-adversarial-review.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency-controller-verification.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency-report.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/adversarial-review.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/application-status.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/evidence-matrix.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/lanes/lane-01-keycloak-sorted-01-10.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/lanes/lane-02-keycloak-sorted-11-20.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/lanes/lane-03-keycloak-sorted-21-30.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/lanes/lane-04-keycloak-sorted-31-38.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/lanes/lane-05-semantic-risk-sample.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/per-file-findings.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/priority-recommendations.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/process/controller_verify.py create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/process/implementation_plan.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/process/task.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/process/verify_quotes.py create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/process/walkthrough.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/sed-proofs.md create mode 100644 docs/superpowers/specs/2026-07-18-keycloak-branch-note-consistency/unresolved-risk-register.md create mode 100644 harness/README.md create mode 100644 harness/adapters/__pycache__/generate.cpython-312.pyc create mode 100644 harness/adapters/__pycache__/generate_rules.cpython-312.pyc create mode 100644 harness/adapters/__pycache__/generate_workflows.cpython-312.pyc create mode 100644 harness/adapters/generate.py create mode 100644 harness/adapters/generate_rules.py create mode 100644 harness/adapters/generate_workflows.py create mode 100644 harness/adapters/platform-metadata.json create mode 100644 harness/runtime/__pycache__/active_structure_check.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/branch_contract_check.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/branch_from_project.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/contract_markdown.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/contract_projection.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/document_commit.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/execution_profile.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/fix_bare_refs.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/fs_transaction.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/layout_check.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/migrate_graph_contracts.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/moc_indexer.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/proof_hard_gate.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/proof_manifest.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/proof_runner.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/quality_gate.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/release_gate.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/semantic_audit.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/semantic_candidate_builder.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/semantic_certificate.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/semantic_regression.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/semantic_surface_extractor.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/source_hygiene.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/template_renderer.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/typed_contract_check.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/vault_migrate.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/workflow_connection_check.cpython-312.pyc create mode 100644 harness/runtime/__pycache__/workflow_dispatch.cpython-312.pyc create mode 100644 harness/runtime/_staging_owasp_csrf/candidate.md create mode 100644 harness/runtime/_staging_owasp_csrf/document-commit.json create mode 100644 harness/runtime/_staging_owasp_csrf/proof-manifest.json create mode 100644 harness/runtime/_staging_owasp_csrf/proof-request.json create mode 100644 harness/runtime/_staging_owasp_csrf/proof-summary.md create mode 100644 harness/runtime/_staging_owasp_csrf/source-fetch.txt create mode 100644 harness/runtime/active_structure_check.py create mode 100644 harness/runtime/branch_contract_check.py create mode 100644 harness/runtime/branch_from_project.py create mode 100644 harness/runtime/contract_markdown.py create mode 100644 harness/runtime/contract_projection.py create mode 100644 harness/runtime/document_commit.py create mode 100644 harness/runtime/execution_profile.py create mode 100644 harness/runtime/fix_bare_refs.py create mode 100644 harness/runtime/fs_transaction.py create mode 100644 harness/runtime/layout_check.py create mode 100644 harness/runtime/migrate_graph_contracts.py create mode 100644 harness/runtime/moc_indexer.py create mode 100644 harness/runtime/proof_hard_gate.py create mode 100644 harness/runtime/proof_manifest.py create mode 100644 harness/runtime/proof_runner.py create mode 100644 harness/runtime/quality_gate.py create mode 100644 harness/runtime/release_gate.py create mode 100644 harness/runtime/semantic_audit.py create mode 100644 harness/runtime/semantic_candidate_builder.py create mode 100644 harness/runtime/semantic_certificate.py create mode 100644 harness/runtime/semantic_regression.py create mode 100644 harness/runtime/semantic_surface_extractor.py create mode 100644 harness/runtime/source_hygiene.py create mode 100644 harness/runtime/template_renderer.py create mode 100644 harness/runtime/typed_contract_check.py create mode 100644 harness/runtime/vault_migrate.py create mode 100644 harness/runtime/workflow_connection_check.py create mode 100644 harness/runtime/workflow_dispatch.py create mode 100644 harness/source/agents/bodies/branch-depth-auditor.md create mode 100644 harness/source/agents/bodies/coverage-auditor.md create mode 100644 harness/source/agents/bodies/extraction-broker.md create mode 100644 harness/source/agents/bodies/project-readiness-auditor.md create mode 100644 harness/source/agents/bodies/wiki-adversarial-reviewer.md create mode 100644 harness/source/agents/bodies/wiki-consistency-auditor.md create mode 100644 harness/source/agents/bodies/wiki-decision-researcher.md create mode 100644 harness/source/agents/bodies/wiki-diagram-reviewer.md create mode 100644 harness/source/agents/bodies/wiki-doc-author.md create mode 100644 harness/source/agents/bodies/wiki-link-verifier.md create mode 100644 harness/source/agents/bodies/wiki-research-lane.md create mode 100644 harness/source/agents/bodies/wiki-semantic-coherence-auditor.md create mode 100644 harness/source/agents/bodies/wiki-source-summarizer.md create mode 100644 harness/source/agents/branch-depth-auditor.json create mode 100644 harness/source/agents/coverage-auditor.json create mode 100644 harness/source/agents/extraction-broker.json create mode 100644 harness/source/agents/project-readiness-auditor.json create mode 100644 harness/source/agents/wiki-adversarial-reviewer.json create mode 100644 harness/source/agents/wiki-consistency-auditor.json create mode 100644 harness/source/agents/wiki-decision-researcher.json create mode 100644 harness/source/agents/wiki-diagram-reviewer.json create mode 100644 harness/source/agents/wiki-doc-author.json create mode 100644 harness/source/agents/wiki-link-verifier.json create mode 100644 harness/source/agents/wiki-research-lane.json create mode 100644 harness/source/agents/wiki-semantic-coherence-auditor.json create mode 100644 harness/source/agents/wiki-source-summarizer.json create mode 100644 harness/source/artifact-schemas/ca-skeleton-frontend/a11y-report.schema.json create mode 100644 harness/source/artifact-schemas/ca-skeleton-frontend/build-manifest.schema.json create mode 100644 harness/source/artifact-schemas/ca-skeleton-frontend/bundle-report.schema.json create mode 100644 harness/source/artifact-schemas/ca-skeleton-frontend/release-verification.schema.json create mode 100644 harness/source/document-relations.json create mode 100644 harness/source/document-semantic-surfaces.json create mode 100644 harness/source/execution-profiles.json create mode 100644 harness/source/generation-manifest.json create mode 100644 harness/source/rule-adapters.json create mode 100644 harness/source/semantic-ontology.json create mode 100644 harness/source/skills/blogify.md create mode 100644 harness/source/skills/branch-from-project.md create mode 100644 harness/source/skills/branch-spec.md create mode 100644 harness/source/skills/branch.md create mode 100644 harness/source/skills/coverage.md create mode 100644 harness/source/skills/daily.md create mode 100644 harness/source/skills/depth.md create mode 100644 harness/source/skills/explain.md create mode 100644 harness/source/skills/ingest.md create mode 100644 harness/source/skills/interviewize.md create mode 100644 harness/source/skills/invest-daily.md create mode 100644 harness/source/skills/invest-decide.md create mode 100644 harness/source/skills/invest-ingest.md create mode 100644 harness/source/skills/invest-plan.md create mode 100644 harness/source/skills/invest-research.md create mode 100644 harness/source/skills/invest-review.md create mode 100644 harness/source/skills/lint.md create mode 100644 harness/source/skills/migrate-claims.md create mode 100644 harness/source/skills/project-spec.md create mode 100644 harness/source/skills/project.md create mode 100644 harness/source/skills/projectize.md create mode 100644 harness/source/skills/query.md create mode 100644 harness/source/skills/sync.md create mode 100644 harness/source/skills/tag.md create mode 100644 harness/source/typed-contracts.json create mode 100644 harness/source/vault-layout.json create mode 100644 harness/source/workflows/blogify.json create mode 100644 harness/source/workflows/branch-from-project.json create mode 100644 harness/source/workflows/branch-spec.json create mode 100644 harness/source/workflows/branch.json create mode 100644 harness/source/workflows/coverage.json create mode 100644 harness/source/workflows/daily.json create mode 100644 harness/source/workflows/depth.json create mode 100644 harness/source/workflows/explain.json create mode 100644 harness/source/workflows/ingest.json create mode 100644 harness/source/workflows/interviewize.json create mode 100644 harness/source/workflows/invest-daily.json create mode 100644 harness/source/workflows/invest-decide.json create mode 100644 harness/source/workflows/invest-ingest.json create mode 100644 harness/source/workflows/invest-plan.json create mode 100644 harness/source/workflows/invest-research.json create mode 100644 harness/source/workflows/invest-review.json create mode 100644 harness/source/workflows/lint.json create mode 100644 harness/source/workflows/migrate-claims.json create mode 100644 harness/source/workflows/project-spec.json create mode 100644 harness/source/workflows/project.json create mode 100644 harness/source/workflows/projectize.json create mode 100644 harness/source/workflows/query.json create mode 100644 harness/source/workflows/sync.json create mode 100644 harness/source/workflows/tag.json create mode 100644 harness/state/commit-runs/samesite-cookie-mdn/candidate.md create mode 100644 harness/state/commit-runs/samesite-cookie-mdn/document-commit.json create mode 100644 harness/state/commit-runs/samesite-cookie-mdn/proof-manifest.json create mode 100644 harness/state/commit-runs/samesite-cookie-mdn/proof-request.json create mode 100644 harness/state/commit-runs/samesite-cookie-mdn/proof-summary.md create mode 100644 harness/state/commit-runs/samesite-cookie-mdn/source-fetch.txt create mode 100644 harness/state/semantic-certificates/028d796257593f29fa5962255a0bde4c75db268ac9085bf4739e432ab8b2e50f/d22275b5740a519599d3e92d67a9a460cdf35b7fcb4801e15dd1a65edb594b56.json create mode 100644 harness/state/semantic-certificates/02cf9d284c76fcdb39ec8a0c60121584eedd71a0e94367a5fb119e583eab369b/ff70c5f51e1d62900fe66452673109f8fe4f1bc0329ea492e961d447119fd9b6.json create mode 100644 harness/state/semantic-certificates/09116c13c5b25234dfa58c700fe589e56dd281baaa22e8e300cd4d6dd6f69dfb/17bf090e5f3daa25ebc29c1677997bf98db56dc0bd283ac9b62174758ca0c76d.json create mode 100644 harness/state/semantic-certificates/0d0f80e31b5f216f8511a295ffae4b8745ab8821dfc6e49c6a234f006b93c33f/0c1f3d22fdc729c013ddd9420d4d3822187ff38fbd04a42c970414d6d47f4e06.json create mode 100644 harness/state/semantic-certificates/0d0f80e31b5f216f8511a295ffae4b8745ab8821dfc6e49c6a234f006b93c33f/22a1555bc2e32ed99e8951a5b0e21c7b9a0028da969bcbbd6dcaa7a25d1fccab.json create mode 100644 harness/state/semantic-certificates/10affe6752bb478c4c1079bc82652bf3c8627d68f6111e5110662b8f8c56fa29/dfa8f18c855db22d25a8090d8aee93046b558c1ec42d61a501d77b6bda919e16.json create mode 100644 harness/state/semantic-certificates/2703a7c6e4b30861dcc31a7b4ba83bac1d7b207f4f621a91c4b25d05fde4ba64/36d5371e9609dbeb6b9f2ec22d0a0979a8902896d3b6c7845447fee4234cb563.json create mode 100644 harness/state/semantic-certificates/3064402e6ff5407708ff81764f7ab0f9bf17925185157890125a68b285504e8b/7c51d963ffc0749c68c2a0128923a22b19d736189029c05a94d0b74fc0d88af4.json create mode 100644 harness/state/semantic-certificates/3372295ac4a7655e7e68d4a65acd143f2c858a126261c28061d7ea7f0cc95193/5cdbbea21dddbd102e2b096ccdf0b281a24ddea2406e34c8f41dfb5dbad2f3e5.json create mode 100644 harness/state/semantic-certificates/3dec2c9b21d4a318b33815ebbbd7d6356594429dbf4a8e96a8502484ece0b176/2892f17c8be9d8a2f4ac25f85256e70b4ec3718f9d692a56a75fe0f8d88cc977.json create mode 100644 harness/state/semantic-certificates/3ef892ce3a733c11128ad27e2efaf7c60dde31622902065df97ccc7d0fa2ba05/727980b7c79b207853b4f637a813a049c441b8ff6e50c30e97bb1d32a023a7d0.json create mode 100644 harness/state/semantic-certificates/6a80f4fa31cb85682f0f5b2e5b2cae2b3f3038b9143a5bce044b35b173df4e8e/7df127b9b2b15480eeec21a36360badcdb36c4cac26674aa701705956383fadb.json create mode 100644 harness/state/semantic-certificates/adf2184e2ab560ff995aafb80430a3b69b635754a759d3a5a829be34786e98f4/6d9b7e25716697a12113c493964bdf391df37c6b29e981ef49ca22ba3598660f.json create mode 100644 harness/state/semantic-certificates/bf81339af7b1675cacfced0cb921ca3d9ddfcb5a5d3ad20b5643432036d705cb/0bceff0596ad4407a633b3c73905f8ead3d9260b57a444cb8aa150f15dc8c0bf.json create mode 100644 harness/state/semantic-certificates/cd57931a048eff49d788e00b585deb922615310f00e6417b8f0555b96baf4746/e0fca6bc00c98cf9dd8bb67fdb4abccfc0586efc3eb00e5b213f13a578c496e6.json create mode 100644 harness/state/semantic-certificates/d21d3ca6a7591b5e14a2c66eec2554a0c67e94a04e870669ed1f49ec9c81f4b6/e7934a7e7d271d8f1d066181cbc3789577a309bd926310745c25a0bc14748049.json create mode 100644 harness/state/semantic-certificates/d583fb979f21acc2fabdbb1530784e5ae919208912830f4cf737c9ade26ed8d8/9af7aac8495239c138330734068cad212e2d7a3fc8c960b1d336bae61022717b.json create mode 100644 harness/state/semantic-certificates/e121c749bd6dbd1d31b1dbbe7babad7be81c8768fcd54a72f2d44905b946d081/4f435ac10fc9bf2b872487c03216a71a192b1658448419d6ebbf64f939f7c363.json create mode 100644 harness/tests/__pycache__/test_active_structure_check.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_active_structure_check.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_branch_contract_check.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_branch_contract_check.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_branch_from_project.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_branch_from_project.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_contract_projection.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_contract_projection.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_cutover_hardening.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_cutover_hardening.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_document_commit.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_document_commit.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_execution_profile.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_execution_profile.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_fix_bare_refs.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_fix_bare_refs.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_fs_transaction.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_fs_transaction.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_generate_workflows.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_generate_workflows.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_korean_lint.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_korean_lint.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_layout_check.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_layout_check.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_migrate_graph_contracts.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_migrate_graph_contracts.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_moc_indexer.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_moc_indexer.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_new_document_plan.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_new_document_plan.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_proof_hard_gate.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_proof_hard_gate.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_proof_manifest.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_proof_manifest.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_proof_rules.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_proof_rules.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_proof_runner.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_proof_runner.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_quality_gate.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_quality_gate.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_release_gate.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_release_gate.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_rule_generation.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_rule_generation.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_semantic_audit.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_semantic_audit.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_semantic_candidate_builder.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_semantic_candidate_builder.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_semantic_certificate.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_semantic_certificate.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_semantic_regression.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_semantic_regression.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_semantic_surface_extractor.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_semantic_surface_extractor.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_source_hygiene.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_source_hygiene.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_template_renderer.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_template_renderer.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_typed_contract_check.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_typed_contract_check.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_vault_migrate.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_vault_migrate.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_workflow_connection_check.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_workflow_connection_check.cpython-312.pyc create mode 100644 harness/tests/__pycache__/test_workflow_dispatch.cpython-312-pytest-9.0.3.pyc create mode 100644 harness/tests/__pycache__/test_workflow_dispatch.cpython-312.pyc create mode 100644 harness/tests/fixtures/adapter-snapshots.json create mode 100644 harness/tests/fixtures/legacy-semantic-sha256.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-001-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-001-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-002-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-002-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-003-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-003-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-004-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-004-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-005-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-005-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-006-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-006-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-007-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-007-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-008-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-008-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-009-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-009-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-010-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-010-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-011-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A1/a1-011-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-001-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-001-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-002-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-002-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-003-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-003-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-004-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-004-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-005-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-005-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-006-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-006-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-007-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-007-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-008-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-008-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-009-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-009-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-010-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-010-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-011-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-011-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-012-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/A4/a4-012-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-001-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-001-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-002-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-002-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-003-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-003-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-004-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-004-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-005-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-005-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-006-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-006-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-007-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-007-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-008-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-008-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-009-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-009-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-010-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-010-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-011-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-011-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-012-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/D7/d7-012-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-001-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-001-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-002-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-002-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-003-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-003-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-004-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-004-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-005-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-005-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-006-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-006-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-007-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-007-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-008-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-008-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-009-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-009-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-010-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-010-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-011-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-011-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-012-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/DELEG/deleg-012-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-001-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-001-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-002-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-002-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-003-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-003-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-004-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-004-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-005-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-005-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-006-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-006-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-007-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-007-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-008-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-008-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-009-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-009-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-010-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-010-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-011-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-011-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-012-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/E1/e1-012-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-001-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-001-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-002-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-002-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-003-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-003-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-004-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-004-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-005-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-005-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-006-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-006-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-007-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-007-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-008-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-008-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-009-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-009-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-010-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-010-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-011-negative.json create mode 100644 harness/tests/fixtures/semantic-consistency/HUB/hub-011-positive.json create mode 100644 harness/tests/fixtures/semantic-consistency/evaluation-runs/run-1.json create mode 100644 harness/tests/fixtures/semantic-consistency/evaluation-runs/run-2.json create mode 100644 harness/tests/fixtures/semantic-consistency/evaluation-runs/run-3.json create mode 100644 harness/tests/fixtures/semantic-consistency/manifest.json create mode 100644 harness/tests/test_active_structure_check.py create mode 100644 harness/tests/test_branch_contract_check.py create mode 100644 harness/tests/test_branch_from_project.py create mode 100644 harness/tests/test_contract_projection.py create mode 100644 harness/tests/test_cutover_hardening.py create mode 100644 harness/tests/test_document_commit.py create mode 100644 harness/tests/test_execution_profile.py create mode 100644 harness/tests/test_fix_bare_refs.py create mode 100644 harness/tests/test_fs_transaction.py create mode 100644 harness/tests/test_generate_workflows.py create mode 100644 harness/tests/test_layout_check.py create mode 100644 harness/tests/test_migrate_graph_contracts.py create mode 100644 harness/tests/test_moc_indexer.py create mode 100644 harness/tests/test_new_document_plan.py create mode 100644 harness/tests/test_proof_hard_gate.py create mode 100644 harness/tests/test_proof_manifest.py create mode 100644 harness/tests/test_proof_rules.py create mode 100644 harness/tests/test_proof_runner.py create mode 100644 harness/tests/test_quality_gate.py create mode 100644 harness/tests/test_release_gate.py create mode 100644 harness/tests/test_rule_generation.py create mode 100644 harness/tests/test_semantic_audit.py create mode 100644 harness/tests/test_semantic_candidate_builder.py create mode 100644 harness/tests/test_semantic_certificate.py create mode 100644 harness/tests/test_semantic_regression.py create mode 100644 harness/tests/test_semantic_surface_extractor.py create mode 100644 harness/tests/test_source_hygiene.py create mode 100644 harness/tests/test_template_renderer.py create mode 100644 harness/tests/test_typed_contract_check.py create mode 100644 harness/tests/test_vault_migrate.py create mode 100644 harness/tests/test_workflow_connection_check.py create mode 100644 harness/tests/test_workflow_dispatch.py create mode 120000 raw/archive/branch-notes/feature-template-instantiation-contract.md create mode 120000 raw/blog-topics/api-deprecation-sunset-header-migration-window-2026-07-02.md create mode 120000 raw/blog-topics/archunit-generic-return-type-purity-query-port-2026-06-05.md create mode 120000 raw/blog-topics/archunit-jackson-default-typing-cve-2019-14379-block-2026-05-29.md create mode 120000 raw/blog-topics/archunit-testcompileonly-fixture-annotation-pattern-2026-06-02.md create mode 120000 raw/blog-topics/archunit-violations-as-data-pattern-2026-05-28.md create mode 120000 raw/blog-topics/binary-readiness-scorecard-clean-architecture-skeleton-2026-07-02.md create mode 120000 raw/blog-topics/boundary-validation-mapper-responsibility-map-2026-07-02.md create mode 120000 raw/blog-topics/cache-backend-router-fail-open-decorator-2026-07-02.md create mode 120000 raw/blog-topics/cache-consistency-after-commit-stampede-contract-2026-07-02.md create mode 120000 raw/blog-topics/ci-gate-wiring-vs-policy-ownership-2026-06-20.md create mode 120000 raw/blog-topics/clean-architecture-boundary-enforcement-2026-05-28.md create mode 120000 raw/blog-topics/clean-architecture-module-blueprint-2026-05-28.md create mode 120000 raw/blog-topics/clean-architecture-reference-project-adoption-2026-06-17.md create mode 120000 raw/blog-topics/contract-registry-schema-owner-vs-row-owner-gate-2026-06-20.md create mode 120000 raw/blog-topics/contract-verification-suite-release-gates-2026-07-02.md create mode 120000 raw/blog-topics/digest-first-java-release-pipeline-2026-06-21.md create mode 120000 raw/blog-topics/distributed-lock-transaction-commit-boundary-2026-07-02.md create mode 120000 raw/blog-topics/domain-modeling-guardrails-as-archunit-fitness-functions-2026-06-05.md create mode 120000 raw/blog-topics/env-example-drift-gate-gradle-2026-06-06.md create mode 120000 raw/blog-topics/executable-clean-architecture-onboarding-2026-06-25.md create mode 120000 raw/blog-topics/five-stage-local-bootstrap-contract-2026-06-24.md create mode 120000 raw/blog-topics/framework-free-method-authorization-clean-architecture-2026-06-08.md create mode 120000 raw/blog-topics/gitea-act-dependency-security-gate-portability-2026-07-02.md create mode 120000 raw/blog-topics/gradle9-java21-static-analysis-baseline-2026-06-20.md create mode 120000 raw/blog-topics/hikaricp-inter-knob-constraints-startup-guard-2026-06-09.md create mode 120000 raw/blog-topics/idempotency-executor-application-layer-clean-architecture-2026-06-09.md create mode 120000 raw/blog-topics/identifier-governance-rule-scoping-by-id-kind-2026-06-01.md create mode 120000 raw/blog-topics/java21-context-propagation-strategy-virtual-threads-2026-07-02.md create mode 120000 raw/blog-topics/jdk-httpclient-dns-connectexception-classification-2026-07-02.md create mode 120000 raw/blog-topics/jvm-oom-vs-container-oomkill-exit-137-2026-07-02.md create mode 120000 raw/blog-topics/logback-layer1-secret-masking-json-vs-pattern-2026-06-14.md create mode 120000 raw/blog-topics/manifest-driven-agent-harness-policy-engine.md create mode 120000 raw/blog-topics/micrometer-meterfilter-resilience4j-functioncounter-2026-07-02.md create mode 120000 raw/blog-topics/nplus1-lab-checkoutable-api-replay-2026-07-15.md create mode 120000 raw/blog-topics/operational-error-envelope-meta-category-migration-2026-06-01.md create mode 120000 raw/blog-topics/persistence-audit-metadata-clean-architecture-2026-07-02.md create mode 120000 raw/blog-topics/post-implementation-knowledge-capture-workflow-2026-05-28.md create mode 120000 raw/blog-topics/repository-capability-archunit-fitness-function-2026-07-02.md create mode 120000 raw/blog-topics/runbook-coverage-junit-contract-test-2026-07-02.md create mode 120000 raw/blog-topics/sample-domain-contract-fixture-clean-architecture-2026-06-10.md create mode 120000 raw/blog-topics/sample-fixture-dual-mode-build-matrix-2026-06-25.md create mode 120000 raw/blog-topics/secret-source-port-restart-only-rotation-2026-07-02.md create mode 120000 raw/blog-topics/skip-locked-outbox-per-aggregate-fifo-gate-2026-06-11.md create mode 120000 raw/blog-topics/spring-actuator-health-probe-group-split-2026-07-02.md create mode 120000 raw/blog-topics/spring-async-taskdecorator-bounded-executor-saturation-shutdown-2026-06-13.md create mode 120000 raw/blog-topics/spring-boot-3-configprops-record-multi-constructor-binding-2026-06-12.md create mode 120000 raw/blog-topics/spring-boot-serialization-contract-pins-2026-07-02.md create mode 120000 raw/blog-topics/spring-boot-startup-exit-code-propagation-2026-06-10.md create mode 120000 raw/blog-topics/spring-conditional-on-property-optional-adapter-template-2026-06-09.md create mode 120000 raw/blog-topics/spring-responseentityexceptionhandler-transport-failure-envelope-2026-07-02.md create mode 120000 raw/blog-topics/spring-security-filter-layer-error-envelope-2026-06-08.md create mode 120000 raw/blog-topics/streaming-response-not-supported-archunit-ban-2026-07-02.md create mode 120000 raw/blog-topics/test-taxonomy-archunit-enforcement-2026-06-19.md create mode 120000 raw/blog-topics/transaction-isolation-vendor-default-pin-2026-07-02.md create mode 120000 raw/blog-topics/transaction-port-abstraction-over-spring-transactional-2026-05-28.md create mode 120000 raw/blog-topics/trivy-suppression-governance-static-gate-2026-06-20.md create mode 120000 raw/blog-topics/ulid-crockford-base32-excluded-letters-2026-06-01.md create mode 120000 raw/blog-topics/w3c-traceparent-fork-activated-seam-2026-07-02.md create mode 120000 raw/blog-topics/webhook-full-jitter-dlq-observability-2026-07-02.md create mode 120000 raw/blog-topics/webhook-signature-replay-contract-2026-07-02.md create mode 120000 raw/blog-topics/webhook-ssrf-egress-proxy-redirect-block-2026-07-02.md create mode 120000 raw/branch-notes/chore-harness-policy-engine-alignment.md create mode 120000 raw/branch-notes/chore-ulid-to-uuidv7.md create mode 120000 raw/branch-notes/experiment-nplus1-feed-api-replay.md create mode 120000 raw/branch-notes/experiment-nplus1-highlight-feed.md create mode 120000 raw/branch-notes/feature-accessibility-baseline-contract.md create mode 120000 raw/branch-notes/feature-api-client-response-envelope-contract.md create mode 120000 raw/branch-notes/feature-api-compatibility-deprecation-contract.md create mode 120000 raw/branch-notes/feature-api-contract-baseline.md create mode 120000 raw/branch-notes/feature-application-port-usecase-contract.md create mode 120000 raw/branch-notes/feature-application-query-bypass-contract.md create mode 120000 raw/branch-notes/feature-architecture-enforcement-rules.md create mode 120000 raw/branch-notes/feature-async-ui-state-contract.md create mode 120000 raw/branch-notes/feature-authentication-authorization-contract.md create mode 120000 raw/branch-notes/feature-background-job-async-contract.md create mode 120000 raw/branch-notes/feature-boundary-mapper-viewmodel-contract.md create mode 120000 raw/branch-notes/feature-boundary-validation-mapping-contract.md create mode 120000 raw/branch-notes/feature-build-release-supply-chain-contract.md create mode 120000 raw/branch-notes/feature-business-rule-validation-contract.md create mode 120000 raw/branch-notes/feature-cache-consistency-contract.md create mode 120000 raw/branch-notes/feature-cachestore-multi-backend-router.md create mode 120000 raw/branch-notes/feature-ci-quality-gates-contract.md create mode 120000 raw/branch-notes/feature-container-runtime-contract.md create mode 120000 raw/branch-notes/feature-contract-registry-governance.md create mode 120000 raw/branch-notes/feature-contract-verification-test-suite.md create mode 120000 raw/branch-notes/feature-data-retention-privacy-contract.md create mode 120000 raw/branch-notes/feature-database-connection-pool-contract.md create mode 120000 raw/branch-notes/feature-dependency-vulnerability-management-contract.md create mode 120000 raw/branch-notes/feature-developer-experience-contract.md create mode 120000 raw/branch-notes/feature-distributed-lock-contract.md create mode 120000 raw/branch-notes/feature-distributed-tracing-contract.md create mode 120000 raw/branch-notes/feature-domain-event-outbox-contract.md create mode 120000 raw/branch-notes/feature-domain-feature-onboarding-contract.md create mode 120000 raw/branch-notes/feature-domain-modeling-guardrails.md create mode 120000 raw/branch-notes/feature-env-driven-runtime-configuration.md create mode 120000 raw/branch-notes/feature-file-resource-handling-contract.md create mode 120000 raw/branch-notes/feature-frontend-architecture-enforcement-lint-contract.md create mode 120000 raw/branch-notes/feature-frontend-auth-session-integration-contract.md create mode 120000 raw/branch-notes/feature-frontend-browser-security-boundary-contract.md create mode 120000 raw/branch-notes/feature-frontend-build-bundle-supply-chain-contract.md create mode 120000 raw/branch-notes/feature-frontend-ci-quality-gates-contract.md create mode 120000 raw/branch-notes/feature-frontend-clean-architecture-layering-contract.md create mode 120000 raw/branch-notes/feature-frontend-contract-compatibility-governance.md create mode 120000 raw/branch-notes/feature-frontend-contract-registry-governance.md create mode 120000 raw/branch-notes/feature-frontend-env-runtime-config-contract.md create mode 120000 raw/branch-notes/feature-frontend-error-classification-boundary-contract.md create mode 120000 raw/branch-notes/feature-frontend-observability-logging-trace-contract.md create mode 120000 raw/branch-notes/feature-frontend-operational-runbook-contract.md create mode 120000 raw/branch-notes/feature-frontend-project-bootstrap-toolchain-contract.md create mode 120000 raw/branch-notes/feature-frontend-release-cache-rollback-contract.md create mode 120000 raw/branch-notes/feature-frontend-render-recovery-boundary-contract.md create mode 120000 raw/branch-notes/feature-frontend-storage-registry-contract.md create mode 120000 raw/branch-notes/feature-frontend-test-taxonomy-contract.md create mode 120000 raw/branch-notes/feature-implementation-readiness-scorecard.md create mode 120000 raw/branch-notes/feature-integration-adapter-templates.md create mode 120000 raw/branch-notes/feature-keycloak-account-linking-spa-ux.md create mode 120000 raw/branch-notes/feature-keycloak-account-linking-sub-vs-email.md create mode 120000 raw/branch-notes/feature-keycloak-bff-csrf-samesite-defense.md create mode 120000 raw/branch-notes/feature-keycloak-bff-oauth2login-session.md create mode 120000 raw/branch-notes/feature-keycloak-bff-vs-spa-direct.md create mode 120000 raw/branch-notes/feature-keycloak-docker-compose-stack.md create mode 120000 raw/branch-notes/feature-keycloak-edge-forwardauth-google-federation.md create mode 120000 raw/branch-notes/feature-keycloak-edge-forwardauth-no-google.md create mode 120000 raw/branch-notes/feature-keycloak-federation-spa-zero-change.md create mode 120000 raw/branch-notes/feature-keycloak-first-broker-login-flow.md create mode 120000 raw/branch-notes/feature-keycloak-four-pattern-tradeoff-matrix.md create mode 120000 raw/branch-notes/feature-keycloak-google-claim-attribute-mapping.md create mode 120000 raw/branch-notes/feature-keycloak-google-redirect-uri-policy.md create mode 120000 raw/branch-notes/feature-keycloak-header-spoofing-defense.md create mode 120000 raw/branch-notes/feature-keycloak-https-termination-caddy-nginx.md create mode 120000 raw/branch-notes/feature-keycloak-idp-brokering-google-client.md create mode 120000 raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role.md create mode 120000 raw/branch-notes/feature-keycloak-internal-spa-direct-google-federation.md create mode 120000 raw/branch-notes/feature-keycloak-internal-spa-direct-no-google.md create mode 120000 raw/branch-notes/feature-keycloak-iss-claim-hostname-mismatch.md create mode 120000 raw/branch-notes/feature-keycloak-nginx-auth-request-integration.md create mode 120000 raw/branch-notes/feature-keycloak-oauth2-proxy-oidc-flow.md create mode 120000 raw/branch-notes/feature-keycloak-patterns.md create mode 120000 raw/branch-notes/feature-keycloak-pkce-flow-stages.md create mode 120000 raw/branch-notes/feature-keycloak-public-domain-tunneling.md create mode 120000 raw/branch-notes/feature-keycloak-realm-client-export.md create mode 120000 raw/branch-notes/feature-keycloak-refresh-rotation-and-logout.md create mode 120000 raw/branch-notes/feature-keycloak-refresh-token-rotation.md create mode 120000 raw/branch-notes/feature-keycloak-reverse-proxy-headers.md create mode 120000 raw/branch-notes/feature-keycloak-single-ec2-google-federation.md create mode 120000 raw/branch-notes/feature-keycloak-single-ec2-no-google.md create mode 120000 raw/branch-notes/feature-keycloak-spa-token-storage-tradeoff.md create mode 120000 raw/branch-notes/feature-keycloak-spring-rs-audience-validator.md create mode 120000 raw/branch-notes/feature-keycloak-spring-rs-role-mapping.md create mode 120000 raw/branch-notes/feature-keycloak-three-leg-trust-chain.md create mode 120000 raw/branch-notes/feature-keycloak-traefik-forwardauth-alternative.md create mode 120000 raw/branch-notes/feature-keycloak-vanilla-js-spa-pkce.md create mode 120000 raw/branch-notes/feature-log-management-contract.md create mode 120000 raw/branch-notes/feature-management-actuator-security-contract.md create mode 120000 raw/branch-notes/feature-messaging-multibroker-router.md create mode 120000 raw/branch-notes/feature-metrics-alerting-contract.md create mode 120000 raw/branch-notes/feature-migration-startup-contract.md create mode 120000 raw/branch-notes/feature-notification-provider-spi.md create mode 120000 raw/branch-notes/feature-operational-error-observability-foundation.md create mode 120000 raw/branch-notes/feature-operational-runbook-contract.md create mode 120000 raw/branch-notes/feature-outbound-http-client-baseline.md create mode 120000 raw/branch-notes/feature-persistence-auditing-contract.md create mode 120000 raw/branch-notes/feature-persistence-failure-baseline.md create mode 120000 raw/branch-notes/feature-rate-limit-idempotency-contract.md create mode 120000 raw/branch-notes/feature-repository-access-permission-contract.md create mode 120000 raw/branch-notes/feature-resource-identifier-contract.md create mode 120000 raw/branch-notes/feature-routing-navigation-guard-contract.md create mode 120000 raw/branch-notes/feature-runtime-context-propagation-contract.md create mode 120000 raw/branch-notes/feature-runtime-health-lifecycle-contract.md create mode 120000 raw/branch-notes/feature-runtime-schema-validation-contract.md create mode 120000 raw/branch-notes/feature-sample-domain-contract-fixture.md create mode 120000 raw/branch-notes/feature-sample-feature-slice-contract-fixture.md create mode 120000 raw/branch-notes/feature-sample-portfolio-public-access.md create mode 120000 raw/branch-notes/feature-sample-removal-adoption-contract.md create mode 120000 raw/branch-notes/feature-schema-serialization-contract.md create mode 120000 raw/branch-notes/feature-secrets-config-source-contract.md create mode 120000 raw/branch-notes/feature-security-operational-baseline.md create mode 120000 raw/branch-notes/feature-server-state-caching-contract.md create mode 120000 raw/branch-notes/feature-skeleton-package-blueprint-contract.md create mode 120000 raw/branch-notes/feature-startup-failure-log-suppression.md create mode 120000 raw/branch-notes/feature-static-analysis-quality-contract.md create mode 120000 raw/branch-notes/feature-streaming-response-contract.md create mode 120000 raw/branch-notes/feature-tailwind-design-token-styling-contract.md create mode 120000 raw/branch-notes/feature-tenant-context-policy.md create mode 120000 raw/branch-notes/feature-test-taxonomy-fixture-contract.md create mode 120000 raw/branch-notes/feature-transaction-concurrency-contract.md create mode 120000 raw/branch-notes/feature-web-vitals-performance-budget-contract.md create mode 120000 raw/branch-notes/feature-webhook-outbound-contract.md create mode 120000 raw/company-tech-blogs/adapter-togglz-ff4j-feature-toggle-library.md create mode 120000 raw/company-tech-blogs/api-versioning-github-rest-date-header.md create mode 120000 raw/company-tech-blogs/api-versioning-stripe-date-based.md create mode 120000 raw/company-tech-blogs/arhohuttunen-hexagonal-architecture-spring-boot.md create mode 120000 raw/company-tech-blogs/aws-iam-arn-format.md create mode 120000 raw/company-tech-blogs/axonframework-transactionmanager-spring-adapter.md create mode 120000 raw/company-tech-blogs/brandur-stripe-idempotency-keys.md create mode 120000 raw/company-tech-blogs/buckpal-archunit-lombok-allowlist-direct-transactional.md create mode 120000 raw/company-tech-blogs/cache-woowahan-after-commit-invalidation.md create mode 120000 raw/company-tech-blogs/ci-flaky-test-quarantine-spotify-google.md create mode 120000 raw/company-tech-blogs/config-launchdarkly-feature-flag-best-practice.md create mode 120000 raw/company-tech-blogs/container-woowahan-spring-native-tradeoffs.md create mode 120000 raw/company-tech-blogs/cqrs-lite-clean-architecture-read-path-bypass-wakita.md create mode 120000 raw/company-tech-blogs/curity-bff-pattern-spa.md create mode 120000 raw/company-tech-blogs/curity-oauth2-scope-vs-permission-naming.md create mode 120000 raw/company-tech-blogs/custom-transaction-interceptor-catnipcoder.md create mode 120000 raw/company-tech-blogs/deliberate-practice-software-developers-redgreencode.md create mode 120000 raw/company-tech-blogs/domain-event-sourcing-vs-cqrs-greg-young.md create mode 120000 raw/company-tech-blogs/domain-woowahan-ddd-aggregate-techblog.md create mode 120000 raw/company-tech-blogs/explicit-architecture-ddd-hexagonal-cqrs-hgraca.md create mode 120000 raw/company-tech-blogs/feature-first-sahibinden-package-by-layer-vs-feature.md create mode 120000 raw/company-tech-blogs/file-clamav-icap-gateway-scan.md create mode 120000 raw/company-tech-blogs/github-api-error-format.md create mode 120000 raw/company-tech-blogs/github-graphql-global-node-id.md create mode 120000 raw/company-tech-blogs/hexagonal-reflectoring-transactional-placement.md create mode 120000 raw/company-tech-blogs/hexagonal-woowahan-techblog-2023.md create mode 120000 raw/company-tech-blogs/idempotency-brandur-stripe-postgres.md create mode 120000 raw/company-tech-blogs/idempotency-redis-vs-db-storage.md create mode 120000 raw/company-tech-blogs/idempotency-toss-payments-techblog.md create mode 120000 raw/company-tech-blogs/jwks-workos-unknown-kid-refresh-rate-limit-pattern.md create mode 120000 raw/company-tech-blogs/keycloak-google-login-codemancers.md create mode 120000 raw/company-tech-blogs/keycloak-jwt-role-extraction-betweendata.md create mode 120000 raw/company-tech-blogs/layer-first-kamilmazurek-github-template.md create mode 120000 raw/company-tech-blogs/lock-subskribe-advisory-lock-distributed-consensus.md create mode 120000 raw/company-tech-blogs/metric-toss-payments-alert-severity-techblog.md create mode 120000 raw/company-tech-blogs/micrometer-context-propagation-line-be-hase.md create mode 120000 raw/company-tech-blogs/modulith-arawn-github-modular-monoliths-spring.md create mode 120000 raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md create mode 120000 raw/company-tech-blogs/multitenancy-atlassian-tenant-context.md create mode 120000 raw/company-tech-blogs/multitenancy-auth0-tenant-resolution.md create mode 120000 raw/company-tech-blogs/multitenancy-hybrid-pooled-siloed-mix.md create mode 120000 raw/company-tech-blogs/multitenancy-stripe-citus-schema-per-tenant.md create mode 120000 raw/company-tech-blogs/multitenancy-subdomain-resolution-patterns.md create mode 120000 raw/company-tech-blogs/netflix-tudum-cqrs-separate-read-store-evolution.md create mode 120000 raw/company-tech-blogs/onion-allegro-tech-blog-2023.md create mode 120000 raw/company-tech-blogs/outbound-stripe-rate-limit-retry-engineering.md create mode 120000 raw/company-tech-blogs/outbox-confluent-kafka-connect-smt.md create mode 120000 raw/company-tech-blogs/outbox-netflix-domain-events-cdc.md create mode 120000 raw/company-tech-blogs/outbox-wix-engineering-debezium.md create mode 120000 raw/company-tech-blogs/outbox-woowahan-techblog-pattern.md create mode 120000 raw/company-tech-blogs/percona-uuid-storage-mysql.md create mode 120000 raw/company-tech-blogs/planetscale-nanoid-api.md create mode 120000 raw/company-tech-blogs/postgresql-slow-query-logging-crunchydata.md create mode 120000 raw/company-tech-blogs/privacy-pseudonymization-hmac-vs-tokenization-iapp.md create mode 120000 raw/company-tech-blogs/read-only-tx-hibernate-optimization-vladmihalcea.md create mode 120000 raw/company-tech-blogs/realtime-service-experience-woowahan-websocket.md create mode 120000 raw/company-tech-blogs/retry-aws-exponential-backoff-and-jitter.md create mode 120000 raw/company-tech-blogs/runbook-atlassian-gitops-runbook-as-code.md create mode 120000 raw/company-tech-blogs/runbook-woowahan-incident-techblog.md create mode 120000 raw/company-tech-blogs/runtime-health-datadog-engineering-graceful-shutdown.md create mode 120000 raw/company-tech-blogs/scaffolding-backstage-golden-path-spotify.md create mode 120000 raw/company-tech-blogs/scoped-value-structured-concurrency-softwaremill.md create mode 120000 raw/company-tech-blogs/secrets-1password-developer-secret-references.md create mode 120000 raw/company-tech-blogs/security-toss-actuator-healthcheck.md create mode 120000 raw/company-tech-blogs/security-woowahan-actuator-safe-usage.md create mode 120000 raw/company-tech-blogs/segment-ksuid.md create mode 120000 raw/company-tech-blogs/senior-engineer-competency-mubin-shaikh.md create mode 120000 raw/company-tech-blogs/skillable-hands-on-lab-structure.md create mode 120000 raw/company-tech-blogs/slow-query-datasource-proxy-spring-boot-galovics.md create mode 120000 raw/company-tech-blogs/snowflake-twitter-id.md create mode 120000 raw/company-tech-blogs/spring-modulith-archunit-generated-exemption-and-violations-as-data.md create mode 120000 raw/company-tech-blogs/sse-realtime-notification-woowahan.md create mode 120000 raw/company-tech-blogs/stripe-error-format.md create mode 120000 raw/company-tech-blogs/test-pyramid-vs-trophy-kent-dodds.md create mode 120000 raw/company-tech-blogs/thorben-janssen-hibernate-timestamp-clock-limitation.md create mode 120000 raw/company-tech-blogs/threadlocal-capture-restore-att-israel.md create mode 120000 raw/company-tech-blogs/toss-payments-error-format.md create mode 120000 raw/company-tech-blogs/tracing-datadog-apm-vs-opentelemetry.md create mode 120000 raw/company-tech-blogs/transaction-port-clean-ddd-spring-medium.md create mode 120000 raw/company-tech-blogs/transaction-port-vassilis-soum-github-readme.md create mode 120000 raw/company-tech-blogs/vlad-mihalcea-postgresql-audit-logging-triggers.md create mode 120000 raw/company-tech-blogs/woowahan-hexagonal-multimodule.md create mode 120000 raw/daily-notes/2026-05-27.md create mode 120000 raw/daily-notes/2026-05-28.md create mode 120000 raw/daily-notes/2026-06-14.md create mode 120000 raw/daily-notes/2026-06-30.md create mode 120000 raw/daily-tasks/README.md create mode 120000 raw/daily-tasks/develop/2026-05-29-archunit-controller-domain-return-rule.md create mode 120000 raw/daily-tasks/infra/2026-05-29-actuator-readiness-probe-db-disconnect-detection.md create mode 120000 raw/diagrams/ca-skeleton-frontend/architecture-deployment-2026-07-18.drawio create mode 120000 raw/diagrams/ca-skeleton-frontend/architecture-overview-2026-07-18.drawio create mode 120000 raw/diagrams/ca-skeleton/architecture-modules-2026-05-26.drawio create mode 120000 raw/diagrams/ca-skeleton/architecture-runtime-topology-2026-05-26.drawio create mode 120000 raw/diagrams/clean-architecture-topic/architecture-clean-concentric-2026-07-04.drawio create mode 120000 raw/diagrams/clean-architecture-topic/architecture-clean-concentric-2026-07-04.svg create mode 120000 raw/diagrams/clean-architecture-topic/architecture-hexagonal-2026-07-04.drawio create mode 120000 raw/diagrams/clean-architecture-topic/architecture-hexagonal-2026-07-04.svg create mode 120000 raw/diagrams/clean-architecture-topic/architecture-layered-2026-07-04.drawio create mode 120000 raw/diagrams/clean-architecture-topic/architecture-layered-2026-07-04.svg create mode 120000 raw/diagrams/keycloak-patterns/architecture-p1a-edge-no-google-2026-05-26.drawio create mode 120000 raw/diagrams/keycloak-patterns/architecture-p1b-edge-google-2026-05-26.drawio create mode 120000 raw/diagrams/keycloak-patterns/architecture-p2a-cluster-internal-no-google-2026-05-26.drawio create mode 120000 raw/diagrams/keycloak-patterns/architecture-p2b-cluster-internal-google-2026-05-26.drawio create mode 120000 raw/diagrams/keycloak-patterns/architecture-p3a-single-ec2-no-google-2026-05-26.drawio create mode 120000 raw/diagrams/keycloak-patterns/architecture-p3b-single-ec2-google-2026-05-26.drawio create mode 120000 raw/diagrams/keycloak-patterns/archived/architecture-p3a-single-ec2-no-google-2026-05-26-v1.drawio create mode 120000 raw/diagrams/keycloak-patterns/archived/architecture-p3a-single-ec2-no-google-2026-05-26-v2.drawio create mode 120000 raw/diagrams/nplus1-presentation-prep/architecture-lab-loop-2026-07-20.drawio create mode 120000 raw/errors/apply-patch-auto-approval-rejected-2026-05-28.md create mode 120000 raw/errors/archunit-b7-configprops-nested-record-accessor-outbound-2026-06-13.md create mode 120000 raw/errors/archunit-b7-configuration-bean-factory-return-type-2026-06-09.md create mode 120000 raw/errors/archunit-empty-should-anchor-2026-05-27.md create mode 120000 raw/errors/archunit-importpackages-empty-vacuous-stale-build-2026-06-20.md create mode 120000 raw/errors/archunit-no-uuid-random-trace-id-false-positive-2026-06-01.md create mode 120000 raw/errors/archunit-test-scope-sample-ticket-inclusion-2026-05-28.md create mode 120000 raw/errors/archunit-testcompileonly-class-loading-2026-06-02.md create mode 120000 raw/errors/bootstrap-postgres-port-collision-2026-06-24.md create mode 120000 raw/errors/ca-comment-to-readme-subagents-overstrip-runtime-strings.md create mode 120000 raw/errors/ca-gitignored-seed-divergence-at-rebase.md create mode 120000 raw/errors/ca-public-path-snapshot-scope-violation.md create mode 120000 raw/errors/ca-tmpl-import-gate-false-positive-shared-contract.md create mode 120000 raw/errors/ca-tmpl-preexisting-check-baseline-failures-2026-07-20.md create mode 120000 raw/errors/ci-fan-in-skipped-not-failed-and-gitignored-config-2026-06-20.md create mode 120000 raw/errors/contract-registry-reference-row-universal-column-false-fail-2026-06-20.md create mode 120000 raw/errors/developer-experience-contract-agents-bridge-2026-07-15.md create mode 120000 raw/errors/flyway-launcher-divergent-migration-set-shared-dev-db-2026-06-12.md create mode 120000 raw/errors/gitea-act-action-tag-and-dependency-graph-2026-06-20.md create mode 120000 raw/errors/gitea-act-missing-jq-job-bootstrap-2026-06-23.md create mode 120000 raw/errors/global-sed-env-rename-pitfalls-2026-06-06.md create mode 120000 raw/errors/gradle-custom-source-set-isolation-failures-2026-06-25.md create mode 120000 raw/errors/gradle-strict-lock-stale-entry-non-resolvable-config-2026-07-08.md create mode 120000 raw/errors/gradle-wrapper-lock-read-only-sandbox-2026-06-10.md create mode 120000 raw/errors/gradle-wrapper-readonly-cache-2026-05-28.md create mode 120000 raw/errors/gradle-wrapper-sandbox-lock-2026-06-25.md create mode 120000 raw/errors/gradle-wrapper-sandbox-lock-readiness-scorecard-2026-06-26.md create mode 120000 raw/errors/hibernate-dto-projection-explain-width-not-narrower-2026-07-13.md create mode 120000 raw/errors/hibernate-getcollectionfetchcount-batch-semantics-2026-07-13.md create mode 120000 raw/errors/hibernate7-hhh90003004-collection-fetch-paging-2026-07-13.md create mode 120000 raw/errors/idempotency-column-definition-base-check-failure-2026-07-15.md create mode 120000 raw/errors/idempotency-expired-row-reclaim-409-loop-2026-06-09.md create mode 120000 raw/errors/internal-auth-misconfiguration-retryable-invariant-conflict-2026-06-08.md create mode 120000 raw/errors/jdk-httpclient-dns-unresolvedaddress-connectexception-2026-06-11.md create mode 120000 raw/errors/jpa-repository-scan-miss-multimodule-2026-06-10.md create mode 120000 raw/errors/logback-shared-jvm-test-leak-pii-contract-2026-06-23.md create mode 120000 raw/errors/mapping-exception-location-archunit-catch-2026-05-29.md create mode 120000 raw/errors/method-security-cglib-vs-jdk-proxy-usecase-injection-2026-06-08.md create mode 120000 raw/errors/method-security-class-pointcut-final-usecase-bean-2026-06-12.md create mode 120000 raw/errors/micrometer-meterfilter-replacetagvalues-functioncounter-2026-06-11.md create mode 120000 raw/errors/mockmvc-406-produces-accept-double-fault-2026-06-02.md create mode 120000 raw/errors/onboarding-fixture-package-path-mismatch-2026-06-25.md create mode 120000 raw/errors/responseentityexceptionhandler-ambiguous-exception-handler-2026-06-02.md create mode 120000 raw/errors/sample-portfolio-flyway-out-of-order-2026-06-23.md create mode 120000 raw/errors/sample-portfolio-oauth2-resource-server-dependency-2026-05-27.md create mode 120000 raw/errors/sample-portfolio-tomcat-port-in-use-check-2026-07-03.md create mode 120000 raw/errors/sample-ticket-oauth2-resource-server-dependency-2026-05-27.md create mode 120000 raw/errors/sandbox-build-verification-boundaries-2026-06-21.md create mode 120000 raw/errors/scheduled-reaper-wrong-config-prefix-2026-06-09.md create mode 120000 raw/errors/slim-jre-random-generator-missing-2026-06-24.md create mode 120000 raw/errors/spanerrorrecorder-constructor-breaks-webmvctest-slice-2026-06-14.md create mode 120000 raw/errors/spotbugs-commons-lang3-bom-downgrade-noclassdef-2026-06-20.md create mode 120000 raw/errors/spring-boot-four-jackson-three-migration-2026-06-30.md create mode 120000 raw/errors/spring-boot-record-multi-constructor-no-default-constructor-2026-06-12.md create mode 120000 raw/errors/spring-componentcan-broad-scan-test-inner-config-collision-2026-06-17.md create mode 120000 raw/errors/spring-componentcan-multimodule-overlap-collision-2026-06-23.md create mode 120000 raw/errors/spring-conditionalonbean-ordering-user-config-vs-autoconfiguration-2026-06-17.md create mode 120000 raw/errors/spring-configuration-bean-factory-method-not-processed-2026-06-11.md create mode 120000 raw/errors/spring-integration-defaultlockrepository-aftersingletons-null-template-2026-06-13.md create mode 120000 raw/errors/spring-jpa-flyway-circular-dependency-2026-06-23.md create mode 120000 raw/errors/spring-jpa-postgres-lob-oid-cast-2026-06-23.md create mode 120000 raw/errors/startup-log-suppression-spotless-format-2026-07-03.md create mode 120000 raw/errors/testcontainers-two-context-shared-datasource-close-2026-06-11.md create mode 120000 raw/errors/ulid-fixture-crockford-u-self-inconsistency-2026-06-01.md create mode 120000 raw/errors/webmvctest-component-filter-constructor-dep-breaks-slice-2026-06-14.md create mode 120000 raw/errors/webmvctest-nested-springbootconfiguration-context-pollution-2026-06-01.md create mode 120000 raw/errors/webmvctest-slice-configprops-enum-placeholder-no-default-2026-06-20.md create mode 120000 raw/interviews/archunit-manual-importer-vs-analyzeclasses.md create mode 120000 raw/interviews/archunit-static-analysis-limits.md create mode 120000 raw/interviews/archunit-violations-as-data-pattern-2026-06-02.md create mode 120000 raw/interviews/async-executor-saturation-context-propagation-2026-06-13.md create mode 120000 raw/interviews/ci-release-gate-fan-in-blocking-2026-06-20.md create mode 120000 raw/interviews/clean-architecture-boundary-enforcement.md create mode 120000 raw/interviews/clean-architecture-domain-onboarding-guardrails.md create mode 120000 raw/interviews/clean-architecture-identifier-generation.md create mode 120000 raw/interviews/clean-architecture-method-authorization-without-spring-coupling-2026-06-08.md create mode 120000 raw/interviews/clean-architecture-module-blueprint.md create mode 120000 raw/interviews/crown-one-query-vs-cqrs-lite-read-model.md create mode 120000 raw/interviews/deterministic-logback-asyncappender-drop-metric-test-2026-06-14.md create mode 120000 raw/interviews/digest-first-supply-chain-release-gates.md create mode 120000 raw/interviews/domain-modeling-guardrails-archunit-2026-06-05.md create mode 120000 raw/interviews/formatter-vs-style-linter-responsibility-split-2026-06-20.md create mode 120000 raw/interviews/gradle-sample-off-test-classpath-isolation.md create mode 120000 raw/interviews/idempotency-rate-limit-design-tradeoffs-2026-06-09.md create mode 120000 raw/interviews/jwt-resource-server-fine-grained-error-classification-2026-06-08.md create mode 120000 raw/interviews/manifest-driven-multi-platform-agent-harness.md create mode 120000 raw/interviews/native-query-addscalar-runtime-validation.md create mode 120000 raw/interviews/operational-error-envelope-and-observability-foundation.md create mode 120000 raw/interviews/optional-adapter-3-layer-disabled-detection-2026-06-09.md create mode 120000 raw/interviews/post-implementation-knowledge-capture.md create mode 120000 raw/interviews/sample-domain-contract-fixture-clean-architecture.md create mode 120000 raw/interviews/shared-contract-and-sample-isolation.md create mode 120000 raw/interviews/single-command-local-bootstrap.md create mode 120000 raw/interviews/spring-jpa-flyway-initialization-lifecycle-circular-dependency.md create mode 120000 raw/interviews/startup-fail-fast-config-validation-2026-06-06.md create mode 120000 raw/interviews/transaction-port-vs-spring-transactional.md create mode 120000 raw/interviews/transactional-outbox-skip-locked-implementation-2026-06-11.md create mode 120000 raw/interviews/trivy-suppression-dual-control-governance-2026-06-20.md create mode 100644 raw/invest-daily/.gitkeep create mode 120000 raw/invest-daily/2026-06-06.md create mode 120000 raw/invest-daily/2026-06-08.md create mode 100644 raw/invest-ledger/.gitkeep create mode 120000 raw/invest-ledger/ledger.md create mode 100644 raw/invest-research/.gitkeep create mode 120000 raw/invest-research/2026-06-05-passive-diversification-behavior.md create mode 120000 raw/invest-research/2026-06-05-stoploss-takeprofit-tax-accounts.md create mode 120000 raw/invest-research/2026-06-08-broad-equity-etf-100man-candidates.md create mode 120000 raw/invest-research/2026-06-08-isa-vs-general-account-no-income.md create mode 120000 raw/invest-research/2026-06-08-korean-broad-etf-ticker-comparison.md create mode 120000 raw/official-docs/actuator-endpoint-exposure-spring-official.md create mode 120000 raw/official-docs/actuator-istio-sidecar-management-alt.md create mode 120000 raw/official-docs/actuator-management-port-spring-official.md create mode 120000 raw/official-docs/adapter-java-spi-serviceloader.md create mode 120000 raw/official-docs/adapter-spring-boot-autoconfig-custom-starter.md create mode 120000 raw/official-docs/api-versioning-google-aip-180.md create mode 120000 raw/official-docs/arch-acl-microsoft-pattern.md create mode 120000 raw/official-docs/arch-clean-architecture-uncle-bob.md create mode 120000 raw/official-docs/arch-hexagonal-cockburn.md create mode 120000 raw/official-docs/archunit-annotation-as-registry-evaluation.md create mode 120000 raw/official-docs/archunit-conditional-on-property-3-layer-pattern.md create mode 120000 raw/official-docs/archunit-user-guide.md create mode 120000 raw/official-docs/at-transactional-spring-official.md create mode 120000 raw/official-docs/aws-acm-managed-renewal.md create mode 120000 raw/official-docs/aws-alb-target-security-group-restriction-official.md create mode 120000 raw/official-docs/aws-builders-retry-jitter.md create mode 120000 raw/official-docs/aws-cloudfront-origin-shared-secret-header-official.md create mode 120000 raw/official-docs/aws-iam-google-iam-permission-naming-convention.md create mode 120000 raw/official-docs/aws-security-group-referencing-official.md create mode 120000 raw/official-docs/baggage-otel-baggage-api-spec.md create mode 120000 raw/official-docs/baggage-w3c-baggage-spec.md create mode 120000 raw/official-docs/cache-aside-vs-write-through-aws.md create mode 120000 raw/official-docs/cache-caffeine-asyncloadingcache-readme.md create mode 120000 raw/official-docs/cache-redisson-rlock-vs-setnx.md create mode 120000 raw/official-docs/caddy-automatic-https-docs.md create mode 120000 raw/official-docs/calver-spec-calver-official.md create mode 120000 raw/official-docs/certbot-user-guide.md create mode 120000 raw/official-docs/checkstyle-google-style-reference.md create mode 120000 raw/official-docs/chrome-third-party-cookie-policy-google-official.md create mode 120000 raw/official-docs/ci-github-actions-vs-gitlab-comparison.md create mode 120000 raw/official-docs/ci-openapi-snapshot-diff-tooling.md create mode 120000 raw/official-docs/cloudevents-spec-required-attributes.md create mode 120000 raw/official-docs/cloudflare-tunnel-routing-official.md create mode 120000 raw/official-docs/compat-rfc-8594-sunset-header.md create mode 120000 raw/official-docs/config-12-factor-app-config.md create mode 120000 raw/official-docs/config-aws-appconfig-feature-flag-deployment.md create mode 120000 raw/official-docs/config-spring-boot-externalized-configuration.md create mode 120000 raw/official-docs/config-spring-cloud-config-server-official.md create mode 120000 raw/official-docs/config-spring-cloud-kubernetes-configmap-reload.md create mode 120000 raw/official-docs/container-alpine-java-musl-tradeoffs.md create mode 120000 raw/official-docs/container-distroless-google-github.md create mode 120000 raw/official-docs/container-graalvm-native-image-spring-boot.md create mode 120000 raw/official-docs/container-stdout-logging-12factor-official.md create mode 120000 raw/official-docs/cosign-keyless-identity-verification-policy.md create mode 120000 raw/official-docs/cqrs-fowler-bliki.md create mode 120000 raw/official-docs/cqrs-pattern-azure-architecture-center.md create mode 120000 raw/official-docs/crockford-base32-spec.md create mode 120000 raw/official-docs/cuid2-spec.md create mode 120000 raw/official-docs/datasource-micrometer-observation-official.md create mode 120000 raw/official-docs/datasource-proxy-slow-query-official.md create mode 120000 raw/official-docs/dependabot-security-updates-gradle-official.md create mode 120000 raw/official-docs/dependabot-supported-ecosystems-official.md create mode 120000 raw/official-docs/docker-compose-depends-on-healthcheck.md create mode 120000 raw/official-docs/docker-compose-networking-extra-hosts-official.md create mode 120000 raw/official-docs/docker-engine-20-10-release-notes-official.md create mode 120000 raw/official-docs/docker-host-network-driver-official.md create mode 120000 raw/official-docs/docker-port-publishing-loopback-bind-official.md create mode 120000 raw/official-docs/domain-event-fowler-eaa.md create mode 120000 raw/official-docs/domain-fowler-anemic-vs-rich-model.md create mode 120000 raw/official-docs/domain-vaughn-vernon-aggregate-root.md create mode 120000 raw/official-docs/dual-write-antipattern-microservices-io.md create mode 120000 raw/official-docs/dx-devcontainer-spring-boot.md create mode 120000 raw/official-docs/dx-mise-asdf-tool-versioning.md create mode 120000 raw/official-docs/dx-testcontainers-java-best-practices.md create mode 120000 raw/official-docs/ecs-awslogs-stdout-cloudwatch-aws-official.md create mode 120000 raw/official-docs/errorprone-gradle-plugin-readme.md create mode 120000 raw/official-docs/event-sourcing-vs-outbox-microservices-io.md create mode 120000 raw/official-docs/feature-first-uncle-bob-screaming-architecture-2011.md create mode 120000 raw/official-docs/fetch-spec-cors.md create mode 120000 raw/official-docs/file-s3-presigned-url-upload.md create mode 120000 raw/official-docs/file-tus-resumable-upload-protocol.md create mode 120000 raw/official-docs/find-sec-bugs-official.md create mode 120000 raw/official-docs/functional-tx-arrow-kt-resource-docs.md create mode 120000 raw/official-docs/gdpr-cryptographic-erasure-envelope-key-pattern.md create mode 120000 raw/official-docs/github-dependency-review-action.md create mode 120000 raw/official-docs/github-webhook-signature.md create mode 120000 raw/official-docs/google-aip-122-resource-names.md create mode 120000 raw/official-docs/google-aip-127-http-transcoding.md create mode 120000 raw/official-docs/google-aip-132-list-method.md create mode 120000 raw/official-docs/google-aip-136-custom-methods.md create mode 120000 raw/official-docs/google-aip-148-standard-fields.md create mode 120000 raw/official-docs/google-aip-151-long-running-operations.md create mode 120000 raw/official-docs/google-aip-158-pagination.md create mode 120000 raw/official-docs/google-aip-160-filtering.md create mode 120000 raw/official-docs/google-aip-185-resource-versioning.md create mode 120000 raw/official-docs/google-aip-233-batch-create.md create mode 120000 raw/official-docs/google-antigravity-hooks.md create mode 120000 raw/official-docs/google-api-error-format.md create mode 120000 raw/official-docs/google-java-format-readme.md create mode 120000 raw/official-docs/google-oauth-app-verification-state-overview-official.md create mode 120000 raw/official-docs/google-oauth-manage-app-audience-official.md create mode 120000 raw/official-docs/google-oauth2-client-application-types-official.md create mode 120000 raw/official-docs/google-oauth2-policies-environment-separation-official.md create mode 120000 raw/official-docs/google-oauth2-redirect-uri-validation-official.md create mode 120000 raw/official-docs/google-oauth2-web-server-flow-official.md create mode 120000 raw/official-docs/google-oidc-discovery-spec.md create mode 120000 raw/official-docs/google-openid-connect-oidc.md create mode 120000 raw/official-docs/google-sre-workbook-on-call-monitoring.md create mode 120000 raw/official-docs/governance-archunit-official.md create mode 120000 raw/official-docs/gradle-java-library-api-vs-implementation.md create mode 120000 raw/official-docs/gradle-reproducible-archives-working-with-files.md create mode 120000 raw/official-docs/graphql-errors-spec.md create mode 120000 raw/official-docs/hexagonal-cockburn-wikipedia-summary.md create mode 120000 raw/official-docs/hexagonal-thombergs-buckpal-github.md create mode 120000 raw/official-docs/hibernate-slow-query-log-official.md create mode 120000 raw/official-docs/iana-media-types-registry.md create mode 120000 raw/official-docs/idempotency-aws-lambda-powertools.md create mode 120000 raw/official-docs/idempotency-ietf-draft.md create mode 120000 raw/official-docs/idempotency-no-api-level-github-rest.md create mode 120000 raw/official-docs/idempotency-paypal-docs.md create mode 120000 raw/official-docs/idempotency-square-api.md create mode 120000 raw/official-docs/idempotency-stripe-api-ref.md create mode 120000 raw/official-docs/istio-mtls-cert-rotation-official.md create mode 120000 raw/official-docs/jdk-files-createtempfile.md create mode 120000 raw/official-docs/jdk21-threadpoolexecutor-javadoc.md create mode 120000 raw/official-docs/json-api-errors-spec.md create mode 120000 raw/official-docs/jsonapi-pagination-format.md create mode 120000 raw/official-docs/junit5-conditional-env-variable-user-guide.md create mode 120000 raw/official-docs/jwks-keycloak-key-rotation-active-passive.md create mode 120000 raw/official-docs/jwks-nimbus-jose-jwksourcebuilder-spring-integration.md create mode 120000 raw/official-docs/k8s-application-security-checklist-readonly-fs.md create mode 120000 raw/official-docs/k8s-configure-probes-task-page.md create mode 120000 raw/official-docs/k8s-logging-architecture-kubernetes-official.md create mode 120000 raw/official-docs/k8s-network-policy-official.md create mode 120000 raw/official-docs/k8s-pod-lifecycle-probes-concept.md create mode 120000 raw/official-docs/k8s-pod-security-standards-restricted.md create mode 120000 raw/official-docs/keycloak-2500-hostname-v2-release-official.md create mode 120000 raw/official-docs/keycloak-2600-hostname-v1-removed-official.md create mode 120000 raw/official-docs/keycloak-account-console-unlink-lockout-guard-official.md create mode 120000 raw/official-docs/keycloak-authorization-services-realm-client-roles.md create mode 120000 raw/official-docs/keycloak-client-initiated-account-linking.md create mode 120000 raw/official-docs/keycloak-client-pkce-method-enforcement-official.md create mode 120000 raw/official-docs/keycloak-configuring-database.md create mode 120000 raw/official-docs/keycloak-first-broker-login-flow.md create mode 120000 raw/official-docs/keycloak-first-broker-login-verify-authenticators-official.md create mode 120000 raw/official-docs/keycloak-first-login-flow.md create mode 120000 raw/official-docs/keycloak-getting-started-docker.md create mode 120000 raw/official-docs/keycloak-google-idp-setup.md create mode 120000 raw/official-docs/keycloak-health-checks.md create mode 120000 raw/official-docs/keycloak-hostname-configuration.md create mode 120000 raw/official-docs/keycloak-identity-broker-spi.md create mode 120000 raw/official-docs/keycloak-identity-brokering-overview-official.md create mode 120000 raw/official-docs/keycloak-identity-provider-mappers.md create mode 120000 raw/official-docs/keycloak-identity-provider-redirector-default-idp-official.md create mode 120000 raw/official-docs/keycloak-identity-provider-sync-mode-official.md create mode 120000 raw/official-docs/keycloak-identity-provider-trust-email-official.md create mode 120000 raw/official-docs/keycloak-idp-hide-on-login-page-toggle-official.md create mode 120000 raw/official-docs/keycloak-idp-hint-client-suggested-official.md create mode 120000 raw/official-docs/keycloak-import-export-realms.md create mode 120000 raw/official-docs/keycloak-oidc-logout-endpoint-official.md create mode 120000 raw/official-docs/keycloak-refresh-token-rotation-reuse-admin-official.md create mode 120000 raw/official-docs/keycloak-refresh-token-rotation-sessions-official.md create mode 120000 raw/official-docs/keycloak-reverseproxy-official.md create mode 120000 raw/official-docs/keycloak-securing-apps-overview-official.md create mode 120000 raw/official-docs/keycloak-server-containers-docker.md create mode 120000 raw/official-docs/kubernetes-exit-code-observability-termination.md create mode 120000 raw/official-docs/kubernetes-pod-lifecycle-termination.md create mode 120000 raw/official-docs/layer-first-baeldung-clean-architecture-spring-boot.md create mode 120000 raw/official-docs/lock-postgres-advisory-locks.md create mode 120000 raw/official-docs/lock-shedlock-issue-899-non-scheduler-use.md create mode 120000 raw/official-docs/lock-shedlock-readme.md create mode 120000 raw/official-docs/lock-spring-integration-lock-registry.md create mode 120000 raw/official-docs/log-ecs-schema-elastic-official.md create mode 120000 raw/official-docs/log-logback-mask-pattern-converter-official.md create mode 120000 raw/official-docs/log-otel-log-data-model-spec.md create mode 120000 raw/official-docs/lombok-builder-data-features-official.md create mode 120000 raw/official-docs/lychee-link-checker.md create mode 120000 raw/official-docs/mapstruct-generated-annotation-official.md create mode 120000 raw/official-docs/metric-google-ewaschuk-philosophy-on-alerting.md create mode 120000 raw/official-docs/metric-google-sre-slo-burn-rate.md create mode 120000 raw/official-docs/metric-google-sre-workbook-on-call.md create mode 120000 raw/official-docs/metric-micrometer-high-cardinality-tags-detector.md create mode 120000 raw/official-docs/metric-micrometer-histogram-percentile-concepts.md create mode 120000 raw/official-docs/metric-micrometer-naming-convention-official.md create mode 120000 raw/official-docs/metric-otel-metrics-data-model-spec.md create mode 120000 raw/official-docs/metric-prometheus-histograms-vs-summaries-practices.md create mode 120000 raw/official-docs/metric-prometheus-label-cardinality-best-practices.md create mode 120000 raw/official-docs/micrometer-context-propagation-official.md create mode 120000 raw/official-docs/micrometer-context-propagation-purpose-thread-local-accessor.md create mode 120000 raw/official-docs/microservices-io-transactional-outbox.md create mode 120000 raw/official-docs/migration-atlas-schema-as-code.md create mode 120000 raw/official-docs/migration-flyway-official-concepts-and-repair.md create mode 120000 raw/official-docs/migration-k8s-init-container-job-pattern.md create mode 120000 raw/official-docs/migration-liquibase-official-changelog-xml-yaml.md create mode 120000 raw/official-docs/modulith-spring-official-doc.md create mode 120000 raw/official-docs/multitenancy-aws-saas-tenant-isolation-whitepaper.md create mode 120000 raw/official-docs/multitenancy-azure-architecture-patterns.md create mode 120000 raw/official-docs/multitenancy-hibernate-user-guide.md create mode 120000 raw/official-docs/multitenancy-microservices-io-pattern.md create mode 120000 raw/official-docs/mysql-innodb-transaction-isolation-official.md create mode 120000 raw/official-docs/nanoid-spec.md create mode 120000 raw/official-docs/nginx-auth-request-module-official.md create mode 120000 raw/official-docs/nginx-client-max-body-size.md create mode 120000 raw/official-docs/nginx-core-module-location-internal-official.md create mode 120000 raw/official-docs/ngrok-http-tunnel-official.md create mode 120000 raw/official-docs/oauth-v2-1-draft-ietf.md create mode 120000 raw/official-docs/oauth2-browser-based-apps-ietf-draft.md create mode 120000 raw/official-docs/oauth2-pkce-rfc-7636.md create mode 120000 raw/official-docs/oauth2-proxy-behaviour-cookie-vs-bearer-official.md create mode 120000 raw/official-docs/oauth2-proxy-cookie-redirect-flags-official.md create mode 120000 raw/official-docs/oauth2-proxy-endpoints-official.md create mode 120000 raw/official-docs/oauth2-proxy-endpoints-signout-official.md create mode 120000 raw/official-docs/oauth2-proxy-keycloak-oidc-provider-official.md create mode 120000 raw/official-docs/oauth2-proxy-nginx-integration-official.md create mode 120000 raw/official-docs/oauth2-proxy-overview-config-official.md create mode 120000 raw/official-docs/oauth2-proxy-session-storage-official.md create mode 120000 raw/official-docs/oauth2-token-revocation-rfc-7009.md create mode 120000 raw/official-docs/oidc-client-ts-library.md create mode 120000 raw/official-docs/onion-palermo-original-2008.md create mode 120000 raw/official-docs/openapi-spec-3-1-0.md create mode 120000 raw/official-docs/openid-connect-core-id-token-validation.md create mode 120000 raw/official-docs/openjdk-jdk-8196595-container-support.md create mode 120000 raw/official-docs/opentelemetry-http-semconv-migration-guide.md create mode 120000 raw/official-docs/opentelemetry-versioning-stability-spec.md create mode 120000 raw/official-docs/otel-exceptions-semantic-conventions.md create mode 120000 raw/official-docs/outbound-openfeign-declarative-client.md create mode 120000 raw/official-docs/outbound-resilience4j-vs-spring-retry.md create mode 120000 raw/official-docs/outbound-spring-restclient-baseline.md create mode 120000 raw/official-docs/outbound-webclient-vs-restclient-spring.md create mode 120000 raw/official-docs/outbox-debezium-official-docs.md create mode 120000 raw/official-docs/outbox-skip-locked-microservices-io.md create mode 120000 raw/official-docs/owasp-authz-permission-model-abac-rbac.md create mode 120000 raw/official-docs/owasp-content-security-policy-cheat-sheet.md create mode 120000 raw/official-docs/owasp-file-upload-cheat-sheet.md create mode 120000 raw/official-docs/owasp-hsts-cheat-sheet.md create mode 120000 raw/official-docs/owasp-html5-storage-xss-spa.md create mode 120000 raw/official-docs/owasp-logging-cheat-sheet.md create mode 120000 raw/official-docs/owasp-path-traversal.md create mode 120000 raw/official-docs/owasp-ssrf-prevention.md create mode 120000 raw/official-docs/p6spy-configuration-official.md create mode 120000 raw/official-docs/patch-json-merge-rfc7396.md create mode 120000 raw/official-docs/persistence-hikaricp-configuration-knobs.md create mode 120000 raw/official-docs/persistence-hikaricp-pool-sizing-wiki.md create mode 120000 raw/official-docs/persistence-osiv-antipattern-hibernate-vladmihalcea.md create mode 120000 raw/official-docs/persistence-r2dbc-reactive-spring.md create mode 120000 raw/official-docs/persistence-spring-dataaccessexception-hierarchy.md create mode 120000 raw/official-docs/postgres-transaction-isolation-official.md create mode 120000 raw/official-docs/postgresql-slow-query-log-official.md create mode 120000 raw/official-docs/privacy-cryptographic-erasure-nist-sp800-88.md create mode 120000 raw/official-docs/privacy-gdpr-article-25-design.md create mode 120000 raw/official-docs/problem-detail-rfc-7807.md create mode 120000 raw/official-docs/prometheus-alertmanager-silences.md create mode 120000 raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md create mode 120000 raw/official-docs/proxy-pass-request-body-nginx-official.md create mode 120000 raw/official-docs/react-router-official.md create mode 120000 raw/official-docs/react-ui-library-official.md create mode 120000 raw/official-docs/redhat-openjdk-container-awareness-java17.md create mode 120000 raw/official-docs/registry-adr-official.md create mode 120000 raw/official-docs/renovate-gradle-manager-official.md create mode 120000 raw/official-docs/renovate-vulnerability-alerts-gradle-official.md create mode 120000 raw/official-docs/reproducible-builds-org-jvm-guide.md create mode 120000 raw/official-docs/resilience4j-micrometer-module.md create mode 120000 raw/official-docs/retry-aws-well-architected-rel05-bp03.md create mode 120000 raw/official-docs/retry-spring-retry-readme-backoff-defaults.md create mode 120000 raw/official-docs/rfc3339-datetime-utc.md create mode 120000 raw/official-docs/rfc3986-uri-generic-syntax.md create mode 120000 raw/official-docs/rfc6455-websocket.md create mode 120000 raw/official-docs/rfc8996-tls10-tls11-deprecation.md create mode 120000 raw/official-docs/rfc9110-http-semantics.md create mode 120000 raw/official-docs/rfc9111-http-caching.md create mode 120000 raw/official-docs/rfc9112-http-1-1-chunked-transfer.md create mode 120000 raw/official-docs/rfc9421-http-message-signatures.md create mode 120000 raw/official-docs/rfc9457-problem-details-http-apis.md create mode 120000 raw/official-docs/rfc9562-uuid.md create mode 120000 raw/official-docs/runbook-pagerduty-incident-response-doc.md create mode 120000 raw/official-docs/runtime-health-istio-mesh-health-check.md create mode 120000 raw/official-docs/runtime-health-k8s-probes-official.md create mode 120000 raw/official-docs/runtime-health-spring-actuator-groups.md create mode 120000 raw/official-docs/runtime-spring-boot-virtual-threads.md create mode 120000 raw/official-docs/sample-microservices-spring-cloud-github.md create mode 120000 raw/official-docs/sample-realworld-gothinkster-github.md create mode 120000 raw/official-docs/sample-spring-petclinic-github.md create mode 120000 raw/official-docs/scaffolding-cookiecutter-official.md create mode 120000 raw/official-docs/scaffolding-degit-svelte-github.md create mode 120000 raw/official-docs/scaffolding-github-template-repository.md create mode 120000 raw/official-docs/scaffolding-spring-initializr.md create mode 120000 raw/official-docs/schema-avro-evolution-rules.md create mode 120000 raw/official-docs/schema-bigdecimal-money-serialization-java.md create mode 120000 raw/official-docs/schema-jackson-polymorphic-deserialization.md create mode 120000 raw/official-docs/schema-jackson-unknown-field-handling.md create mode 120000 raw/official-docs/schema-protobuf-vs-json-evolution.md create mode 120000 raw/official-docs/scoped-value-jep-446-506-openjdk.md create mode 120000 raw/official-docs/scorecard-aws-well-architected.md create mode 120000 raw/official-docs/scorecard-cis-benchmarks-slsa.md create mode 120000 raw/official-docs/scorecard-opentelemetry-maturity.md create mode 120000 raw/official-docs/secrets-aws-secrets-manager-rotation.md create mode 120000 raw/official-docs/secrets-k8s-secret-external-secrets-operator.md create mode 120000 raw/official-docs/secrets-vault-dynamic-secrets-hashicorp.md create mode 120000 raw/official-docs/security-authorization-cheatsheet-owasp.md create mode 120000 raw/official-docs/security-aws-sigv4-hmac-signing.md create mode 120000 raw/official-docs/security-jwt-rfc-7519-validation.md create mode 120000 raw/official-docs/security-mtls-rfc-8705.md create mode 120000 raw/official-docs/security-oauth2-pkce-rfc-8252.md create mode 120000 raw/official-docs/security-opa-policy-engine-official.md create mode 120000 raw/official-docs/security-spring-jwt-timestamp-validator-clock-skew.md create mode 120000 raw/official-docs/semver-2-0-0-spec-semver-official.md create mode 120000 raw/official-docs/silent-check-sso-third-party-cookies-keycloak-official.md create mode 120000 raw/official-docs/skip-locked-mysql-docs.md create mode 120000 raw/official-docs/skip-locked-postgres-docs.md create mode 120000 raw/official-docs/slsa-v1-provenance-schema.md create mode 120000 raw/official-docs/sonarqube-server-versus-cloud.md create mode 120000 raw/official-docs/spotbugs-gradle-plugin-docs.md create mode 120000 raw/official-docs/spotless-gradle-plugin-readme.md create mode 120000 raw/official-docs/spring-boot-exit-code-generator-startup-failure.md create mode 120000 raw/official-docs/spring-boot-graceful-shutdown-reference.md create mode 120000 raw/official-docs/spring-boot-multipart-reference.md create mode 120000 raw/official-docs/spring-boot-structuring-your-code.md create mode 120000 raw/official-docs/spring-boot-task-execution-scheduling-reference.md create mode 120000 raw/official-docs/spring-boot-test-slices-webmvctest-datajpatest-official.md create mode 120000 raw/official-docs/spring-data-jpa-auditing-official.md create mode 120000 raw/official-docs/spring-data-jpa-enable-jpa-auditing-api.md create mode 120000 raw/official-docs/spring-data-jpa-projections-spring-official.md create mode 120000 raw/official-docs/spring-data-jpa-transactionality-spring-official.md create mode 120000 raw/official-docs/spring-data-pageable-defaults.md create mode 120000 raw/official-docs/spring-executor-configuration-support-javadoc.md create mode 120000 raw/official-docs/spring-framework-observability-context-propagating-task-decorator.md create mode 120000 raw/official-docs/spring-framework-test-enabledif-jupiter-annotation.md create mode 120000 raw/official-docs/spring-framework-threadpooltaskexecutor-javadoc.md create mode 120000 raw/official-docs/spring-mvc-async-streaming.md create mode 120000 raw/official-docs/spring-mvc-rest-exception-handling.md create mode 120000 raw/official-docs/spring-problem-detail.md create mode 120000 raw/official-docs/spring-restclient-builder-reference.md create mode 120000 raw/official-docs/spring-security-authorization-architecture.md create mode 120000 raw/official-docs/spring-security-authorization-defense-in-depth.md create mode 120000 raw/official-docs/spring-security-authorize-http-requests.md create mode 120000 raw/official-docs/spring-security-concurrency-delegating-security-context-executor.md create mode 120000 raw/official-docs/spring-security-method-security.md create mode 120000 raw/official-docs/spring-security-nested-authorities-claim-issue-15201.md create mode 120000 raw/official-docs/spring-security-resource-server-jwt.md create mode 120000 raw/official-docs/spring-smartlifecycle-reference.md create mode 120000 raw/official-docs/spring-streaming-response-body.md create mode 120000 raw/official-docs/spring-transaction-synchronization-manager-javadoc.md create mode 120000 raw/official-docs/spring-transactional-event-listener.md create mode 120000 raw/official-docs/spring-tx-management-reference.md create mode 120000 raw/official-docs/spring-tx-propagation-required-new-nested-official.md create mode 120000 raw/official-docs/stripe-resource-id-convention.md create mode 120000 raw/official-docs/stripe-webhook-signature.md create mode 120000 raw/official-docs/sunset-deprecation-headers-paired-usage.md create mode 120000 raw/official-docs/supply-chain-cosign-keyless-sigstore.md create mode 120000 raw/official-docs/supply-chain-gradle-vs-maven-dependency-locking.md create mode 120000 raw/official-docs/supply-chain-slsa-provenance-framework.md create mode 120000 raw/official-docs/svix-webhook-best-practices.md create mode 120000 raw/official-docs/sysexits-bsd-exit-code-convention.md create mode 120000 raw/official-docs/tailwind-css-utility-first-official.md create mode 120000 raw/official-docs/tanstack-query-server-state-official.md create mode 120000 raw/official-docs/test-taxonomy-practical-pyramid-fowler.md create mode 120000 raw/official-docs/test-taxonomy-testcontainers-official.md create mode 120000 raw/official-docs/third-party-cookie-blocking-safari-webkit-official.md create mode 120000 raw/official-docs/threadlocal-virtual-threads-java21-oracle.md create mode 120000 raw/official-docs/trace-context-w3c-recommendation.md create mode 120000 raw/official-docs/tracing-b3-propagation-zipkin-spec.md create mode 120000 raw/official-docs/tracing-micrometer-observation-introduction.md create mode 120000 raw/official-docs/tracing-otel-sampling-tail-vs-head-spec.md create mode 120000 raw/official-docs/tracing-otel-trace-api-spec.md create mode 120000 raw/official-docs/tracing-spring-boot-3-actuator-tracing-reference.md create mode 120000 raw/official-docs/tracing-w3c-trace-context-spec.md create mode 120000 raw/official-docs/traefik-forwardauth-middleware-official.md create mode 120000 raw/official-docs/traefik-hub-oidc-middleware-official.md create mode 120000 raw/official-docs/traefik-oidc-community-plugin-lukaszraczylo-official.md create mode 120000 raw/official-docs/transaction-template-spring-official.md create mode 120000 raw/official-docs/transactional-outbox-aws-prescriptive-guidance.md create mode 120000 raw/official-docs/trivy-action-github-actions.md create mode 120000 raw/official-docs/trivy-filtering-suppression-policy.md create mode 120000 raw/official-docs/trivy-java-language-coverage.md create mode 120000 raw/official-docs/trivy-severity-exit-code-gating.md create mode 120000 raw/official-docs/ulid-spec.md create mode 120000 raw/official-docs/validation-jakarta-bean-validation-3.0-spec.md create mode 120000 raw/official-docs/verification-approvaltests-snapshot-official.md create mode 120000 raw/official-docs/verification-pact-cdc-official.md create mode 120000 raw/official-docs/verification-spring-cloud-contract-official.md create mode 120000 raw/official-docs/verification-spring-restdocs-official.md create mode 120000 raw/official-docs/vite-build-tool-official.md create mode 120000 raw/official-docs/vuln-severity-cisa-kev-catalog-official.md create mode 120000 raw/official-docs/vuln-severity-cvss-v31-spec-first-official.md create mode 120000 raw/official-docs/whatwg-html-server-sent-events.md create mode 120000 raw/official-docs/zod-runtime-schema-validation-official.md create mode 120000 raw/project-notes/ca-skeleton-frontend-operational-contract.md create mode 120000 raw/project-notes/ca-skeleton-operational-contract.md create mode 120000 raw/project-notes/invest-money-flow-system.md create mode 120000 raw/project-notes/keycloak-patterns-overview.md create mode 120000 raw/project-notes/llm-wiki-server-migration.md create mode 120000 raw/project-notes/nplus1-presentation-prep.md create mode 120000 raw/project-notes/project-infra-overview.md create mode 120000 rules/advisory-depth.md create mode 120000 rules/branch-depth-gate.md create mode 120000 rules/consistency-contract.md create mode 120000 rules/coverage-gate.md create mode 120000 rules/diagram-standards.md create mode 120000 rules/evidence-first-research.md create mode 120000 rules/execution-profiles.md create mode 120000 rules/extraction-tiering.md create mode 120000 rules/linking-rules.md create mode 120000 rules/naming-conventions.md create mode 120000 rules/project-readiness-gate.md create mode 120000 rules/prose-style.md create mode 120000 rules/reporting-standards.md create mode 120000 rules/subagent-input-contracts.md create mode 120000 rules/tag-taxonomy.md create mode 100644 scripts/deep-research/.gitignore create mode 100644 scripts/deep-research/README.md create mode 100644 scripts/deep-research/deep_research/__init__.py create mode 100644 scripts/deep-research/deep_research/__main__.py create mode 100644 scripts/deep-research/deep_research/backends/__init__.py create mode 100644 scripts/deep-research/deep_research/backends/antigravity.py create mode 100644 scripts/deep-research/deep_research/backends/base.py create mode 100644 scripts/deep-research/deep_research/backends/codex.py create mode 100644 scripts/deep-research/deep_research/backends/mock.py create mode 100644 scripts/deep-research/deep_research/config.py create mode 100644 scripts/deep-research/deep_research/core.py create mode 100644 scripts/deep-research/deep_research/extract.py create mode 100644 scripts/deep-research/deep_research/pipeline.py create mode 100644 scripts/deep-research/deep_research/prompts.py create mode 100644 scripts/deep-research/deep_research/report.py create mode 100644 scripts/deep-research/deep_research/schemas.py create mode 100644 scripts/deep-research/deep_research/vote.py create mode 100644 scripts/deep-research/pyproject.toml create mode 100644 scripts/deep-research/tests/__init__.py create mode 100644 scripts/deep-research/tests/test_core.py create mode 100644 scripts/deep-research/tests/test_extract_vote.py create mode 100644 scripts/deep-research/tests/test_pipeline_mock.py create mode 120000 templates/blog-template.md create mode 120000 templates/blog-topic-template.md create mode 120000 templates/branch-note-template.md create mode 120000 templates/branch-report-template.md create mode 120000 templates/concept-template.md create mode 120000 templates/daily-note-template.md create mode 120000 templates/daily-task-develop-template.md create mode 120000 templates/daily-task-infra-template.md create mode 120000 templates/error-note-template.md create mode 120000 templates/explainer-template.md create mode 120000 templates/interview-prep-template.md create mode 120000 templates/interview-template.md create mode 120000 templates/invest-concept-template.md create mode 120000 templates/invest-daily-template.md create mode 120000 templates/invest-field-card-template.md create mode 120000 templates/invest-ledger-template.md create mode 120000 templates/invest-plan-template.md create mode 120000 templates/invest-research-template.md create mode 120000 templates/invest-strategy-template.md create mode 120000 templates/job-posting-template.md create mode 120000 templates/lecture-note-template.md create mode 120000 templates/portfolio-template.md create mode 120000 templates/project-report-template.md create mode 120000 templates/project-template.md create mode 120000 templates/raw-source-template.md create mode 120000 templates/source-summary-template.md create mode 120000 templates/wiki-project-template.md create mode 100644 vault/00-system/.gitkeep create mode 100644 vault/00-system/rules/advisory-depth.md create mode 100644 vault/00-system/rules/branch-depth-gate.md create mode 100644 vault/00-system/rules/consistency-contract.md create mode 100644 vault/00-system/rules/coverage-gate.md create mode 100644 vault/00-system/rules/diagram-standards.md create mode 100644 vault/00-system/rules/evidence-first-research.md create mode 100644 vault/00-system/rules/execution-profiles.md create mode 100644 vault/00-system/rules/extraction-tiering.md create mode 100644 vault/00-system/rules/linking-rules.md create mode 100644 vault/00-system/rules/naming-conventions.md create mode 100644 vault/00-system/rules/project-readiness-gate.md create mode 100644 vault/00-system/rules/prose-style.md create mode 100644 vault/00-system/rules/reporting-standards.md create mode 100644 vault/00-system/rules/subagent-input-contracts.md create mode 100644 vault/00-system/rules/tag-taxonomy.md create mode 100644 vault/00-system/templates/blog-template.md create mode 100644 vault/00-system/templates/blog-topic-template.md create mode 100644 vault/00-system/templates/branch-note-template.md create mode 100644 vault/00-system/templates/branch-report-template.md create mode 100644 vault/00-system/templates/concept-template.md create mode 100644 vault/00-system/templates/daily-note-template.md create mode 100644 vault/00-system/templates/daily-task-develop-template.md create mode 100644 vault/00-system/templates/daily-task-infra-template.md create mode 100644 vault/00-system/templates/error-note-template.md create mode 100644 vault/00-system/templates/explainer-template.md create mode 100644 vault/00-system/templates/interview-prep-template.md create mode 100644 vault/00-system/templates/interview-template.md create mode 100644 vault/00-system/templates/invest-concept-template.md create mode 100644 vault/00-system/templates/invest-daily-template.md create mode 100644 vault/00-system/templates/invest-field-card-template.md create mode 100644 vault/00-system/templates/invest-ledger-template.md create mode 100644 vault/00-system/templates/invest-plan-template.md create mode 100644 vault/00-system/templates/invest-research-template.md create mode 100644 vault/00-system/templates/invest-strategy-template.md create mode 100644 vault/00-system/templates/job-posting-template.md create mode 100644 vault/00-system/templates/lecture-note-template.md create mode 100644 vault/00-system/templates/portfolio-template.md create mode 100644 vault/00-system/templates/project-report-template.md create mode 100644 vault/00-system/templates/project-template.md create mode 100644 vault/00-system/templates/raw-source-template.md create mode 100644 vault/00-system/templates/source-summary-template.md create mode 100644 vault/00-system/templates/wiki-project-template.md create mode 100644 vault/10-projects/.gitkeep create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-accessibility-baseline-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-api-client-response-envelope-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-async-ui-state-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-boundary-mapper-viewmodel-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-architecture-enforcement-lint-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-auth-session-integration-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-browser-security-boundary-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-build-bundle-supply-chain-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-ci-quality-gates-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-clean-architecture-layering-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-contract-compatibility-governance.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-contract-registry-governance.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-env-runtime-config-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-error-classification-boundary-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-observability-logging-trace-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-operational-runbook-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-project-bootstrap-toolchain-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-release-cache-rollback-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-render-recovery-boundary-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-storage-registry-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-frontend-test-taxonomy-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-routing-navigation-guard-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-runtime-schema-validation-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-sample-feature-slice-contract-fixture.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-server-state-caching-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-tailwind-design-token-styling-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/branch-notes/feature-web-vitals-performance-budget-contract.md create mode 100644 vault/10-projects/ca-skeleton-frontend-operational-contract/project-notes/ca-skeleton-frontend-operational-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/chore-harness-policy-engine-alignment.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/chore-ulid-to-uuidv7.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-api-compatibility-deprecation-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-api-contract-baseline.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-application-port-usecase-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-application-query-bypass-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-architecture-enforcement-rules.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-authentication-authorization-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-background-job-async-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-boundary-validation-mapping-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-build-release-supply-chain-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-business-rule-validation-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-cache-consistency-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-cachestore-multi-backend-router.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-ci-quality-gates-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-container-runtime-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-contract-registry-governance.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-contract-verification-test-suite.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-data-retention-privacy-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-database-connection-pool-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-dependency-vulnerability-management-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-developer-experience-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-distributed-lock-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-distributed-tracing-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-domain-event-outbox-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-domain-feature-onboarding-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-domain-modeling-guardrails.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-env-driven-runtime-configuration.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-file-resource-handling-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-implementation-readiness-scorecard.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-integration-adapter-templates.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-log-management-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-management-actuator-security-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-messaging-multibroker-router.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-metrics-alerting-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-migration-startup-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-notification-provider-spi.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-operational-error-observability-foundation.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-operational-runbook-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-outbound-http-client-baseline.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-persistence-auditing-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-persistence-failure-baseline.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-rate-limit-idempotency-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-repository-access-permission-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-resource-identifier-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-runtime-context-propagation-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-runtime-health-lifecycle-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-sample-domain-contract-fixture.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-sample-portfolio-public-access.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-sample-removal-adoption-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-schema-serialization-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-secrets-config-source-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-security-operational-baseline.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-skeleton-package-blueprint-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-startup-failure-log-suppression.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-static-analysis-quality-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-streaming-response-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-tenant-context-policy.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-test-taxonomy-fixture-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-transaction-concurrency-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/branch-notes/feature-webhook-outbound-contract.md create mode 100644 vault/10-projects/ca-skeleton-operational-contract/project-notes/ca-skeleton-operational-contract.md create mode 100644 vault/10-projects/diagrams/ca-skeleton-frontend/architecture-deployment-2026-07-18.drawio create mode 100644 vault/10-projects/diagrams/ca-skeleton-frontend/architecture-overview-2026-07-18.drawio create mode 100644 vault/10-projects/diagrams/ca-skeleton/architecture-modules-2026-05-26.drawio create mode 100644 vault/10-projects/diagrams/ca-skeleton/architecture-runtime-topology-2026-05-26.drawio create mode 100644 vault/10-projects/diagrams/clean-architecture-topic/architecture-clean-concentric-2026-07-04.drawio create mode 100644 vault/10-projects/diagrams/clean-architecture-topic/architecture-clean-concentric-2026-07-04.svg create mode 100644 vault/10-projects/diagrams/clean-architecture-topic/architecture-hexagonal-2026-07-04.drawio create mode 100644 vault/10-projects/diagrams/clean-architecture-topic/architecture-hexagonal-2026-07-04.svg create mode 100644 vault/10-projects/diagrams/clean-architecture-topic/architecture-layered-2026-07-04.drawio create mode 100644 vault/10-projects/diagrams/clean-architecture-topic/architecture-layered-2026-07-04.svg create mode 100644 vault/10-projects/diagrams/keycloak-patterns/architecture-p1a-edge-no-google-2026-05-26.drawio create mode 100644 vault/10-projects/diagrams/keycloak-patterns/architecture-p1b-edge-google-2026-05-26.drawio create mode 100644 vault/10-projects/diagrams/keycloak-patterns/architecture-p2a-cluster-internal-no-google-2026-05-26.drawio create mode 100644 vault/10-projects/diagrams/keycloak-patterns/architecture-p2b-cluster-internal-google-2026-05-26.drawio create mode 100644 vault/10-projects/diagrams/keycloak-patterns/architecture-p3a-single-ec2-no-google-2026-05-26.drawio create mode 100644 vault/10-projects/diagrams/keycloak-patterns/architecture-p3b-single-ec2-google-2026-05-26.drawio create mode 100644 vault/10-projects/diagrams/keycloak-patterns/archived/architecture-p3a-single-ec2-no-google-2026-05-26-v1.drawio create mode 100644 vault/10-projects/diagrams/keycloak-patterns/archived/architecture-p3a-single-ec2-no-google-2026-05-26-v2.drawio create mode 100644 vault/10-projects/diagrams/nplus1-presentation-prep/architecture-lab-loop-2026-07-20.drawio create mode 100644 vault/10-projects/errors/apply-patch-auto-approval-rejected-2026-05-28.md create mode 100644 vault/10-projects/errors/archunit-b7-configprops-nested-record-accessor-outbound-2026-06-13.md create mode 100644 vault/10-projects/errors/archunit-b7-configuration-bean-factory-return-type-2026-06-09.md create mode 100644 vault/10-projects/errors/archunit-empty-should-anchor-2026-05-27.md create mode 100644 vault/10-projects/errors/archunit-importpackages-empty-vacuous-stale-build-2026-06-20.md create mode 100644 vault/10-projects/errors/archunit-no-uuid-random-trace-id-false-positive-2026-06-01.md create mode 100644 vault/10-projects/errors/archunit-test-scope-sample-ticket-inclusion-2026-05-28.md create mode 100644 vault/10-projects/errors/archunit-testcompileonly-class-loading-2026-06-02.md create mode 100644 vault/10-projects/errors/bootstrap-postgres-port-collision-2026-06-24.md create mode 100644 vault/10-projects/errors/ca-comment-to-readme-subagents-overstrip-runtime-strings.md create mode 100644 vault/10-projects/errors/ca-gitignored-seed-divergence-at-rebase.md create mode 100644 vault/10-projects/errors/ca-public-path-snapshot-scope-violation.md create mode 100644 vault/10-projects/errors/ca-tmpl-import-gate-false-positive-shared-contract.md create mode 100644 vault/10-projects/errors/ca-tmpl-preexisting-check-baseline-failures-2026-07-20.md create mode 100644 vault/10-projects/errors/ci-fan-in-skipped-not-failed-and-gitignored-config-2026-06-20.md create mode 100644 vault/10-projects/errors/contract-registry-reference-row-universal-column-false-fail-2026-06-20.md create mode 100644 vault/10-projects/errors/developer-experience-contract-agents-bridge-2026-07-15.md create mode 100644 vault/10-projects/errors/flyway-launcher-divergent-migration-set-shared-dev-db-2026-06-12.md create mode 100644 vault/10-projects/errors/gitea-act-action-tag-and-dependency-graph-2026-06-20.md create mode 100644 vault/10-projects/errors/gitea-act-missing-jq-job-bootstrap-2026-06-23.md create mode 100644 vault/10-projects/errors/global-sed-env-rename-pitfalls-2026-06-06.md create mode 100644 vault/10-projects/errors/gradle-custom-source-set-isolation-failures-2026-06-25.md create mode 100644 vault/10-projects/errors/gradle-strict-lock-stale-entry-non-resolvable-config-2026-07-08.md create mode 100644 vault/10-projects/errors/gradle-wrapper-lock-read-only-sandbox-2026-06-10.md create mode 100644 vault/10-projects/errors/gradle-wrapper-readonly-cache-2026-05-28.md create mode 100644 vault/10-projects/errors/gradle-wrapper-sandbox-lock-2026-06-25.md create mode 100644 vault/10-projects/errors/gradle-wrapper-sandbox-lock-readiness-scorecard-2026-06-26.md create mode 100644 vault/10-projects/errors/hibernate-dto-projection-explain-width-not-narrower-2026-07-13.md create mode 100644 vault/10-projects/errors/hibernate-getcollectionfetchcount-batch-semantics-2026-07-13.md create mode 100644 vault/10-projects/errors/hibernate7-hhh90003004-collection-fetch-paging-2026-07-13.md create mode 100644 vault/10-projects/errors/idempotency-column-definition-base-check-failure-2026-07-15.md create mode 100644 vault/10-projects/errors/idempotency-expired-row-reclaim-409-loop-2026-06-09.md create mode 100644 vault/10-projects/errors/internal-auth-misconfiguration-retryable-invariant-conflict-2026-06-08.md create mode 100644 vault/10-projects/errors/jdk-httpclient-dns-unresolvedaddress-connectexception-2026-06-11.md create mode 100644 vault/10-projects/errors/jpa-repository-scan-miss-multimodule-2026-06-10.md create mode 100644 vault/10-projects/errors/logback-shared-jvm-test-leak-pii-contract-2026-06-23.md create mode 100644 vault/10-projects/errors/mapping-exception-location-archunit-catch-2026-05-29.md create mode 100644 vault/10-projects/errors/method-security-cglib-vs-jdk-proxy-usecase-injection-2026-06-08.md create mode 100644 vault/10-projects/errors/method-security-class-pointcut-final-usecase-bean-2026-06-12.md create mode 100644 vault/10-projects/errors/micrometer-meterfilter-replacetagvalues-functioncounter-2026-06-11.md create mode 100644 vault/10-projects/errors/mockmvc-406-produces-accept-double-fault-2026-06-02.md create mode 100644 vault/10-projects/errors/onboarding-fixture-package-path-mismatch-2026-06-25.md create mode 100644 vault/10-projects/errors/responseentityexceptionhandler-ambiguous-exception-handler-2026-06-02.md create mode 100644 vault/10-projects/errors/sample-portfolio-flyway-out-of-order-2026-06-23.md create mode 100644 vault/10-projects/errors/sample-portfolio-oauth2-resource-server-dependency-2026-05-27.md create mode 100644 vault/10-projects/errors/sample-portfolio-tomcat-port-in-use-check-2026-07-03.md create mode 100644 vault/10-projects/errors/sample-ticket-oauth2-resource-server-dependency-2026-05-27.md create mode 100644 vault/10-projects/errors/sandbox-build-verification-boundaries-2026-06-21.md create mode 100644 vault/10-projects/errors/scheduled-reaper-wrong-config-prefix-2026-06-09.md create mode 100644 vault/10-projects/errors/slim-jre-random-generator-missing-2026-06-24.md create mode 100644 vault/10-projects/errors/spanerrorrecorder-constructor-breaks-webmvctest-slice-2026-06-14.md create mode 100644 vault/10-projects/errors/spotbugs-commons-lang3-bom-downgrade-noclassdef-2026-06-20.md create mode 100644 vault/10-projects/errors/spring-boot-four-jackson-three-migration-2026-06-30.md create mode 100644 vault/10-projects/errors/spring-boot-record-multi-constructor-no-default-constructor-2026-06-12.md create mode 100644 vault/10-projects/errors/spring-componentcan-broad-scan-test-inner-config-collision-2026-06-17.md create mode 100644 vault/10-projects/errors/spring-componentcan-multimodule-overlap-collision-2026-06-23.md create mode 100644 vault/10-projects/errors/spring-conditionalonbean-ordering-user-config-vs-autoconfiguration-2026-06-17.md create mode 100644 vault/10-projects/errors/spring-configuration-bean-factory-method-not-processed-2026-06-11.md create mode 100644 vault/10-projects/errors/spring-integration-defaultlockrepository-aftersingletons-null-template-2026-06-13.md create mode 100644 vault/10-projects/errors/spring-jpa-flyway-circular-dependency-2026-06-23.md create mode 100644 vault/10-projects/errors/spring-jpa-postgres-lob-oid-cast-2026-06-23.md create mode 100644 vault/10-projects/errors/startup-log-suppression-spotless-format-2026-07-03.md create mode 100644 vault/10-projects/errors/testcontainers-two-context-shared-datasource-close-2026-06-11.md create mode 100644 vault/10-projects/errors/ulid-fixture-crockford-u-self-inconsistency-2026-06-01.md create mode 100644 vault/10-projects/errors/webmvctest-component-filter-constructor-dep-breaks-slice-2026-06-14.md create mode 100644 vault/10-projects/errors/webmvctest-nested-springbootconfiguration-context-pollution-2026-06-01.md create mode 100644 vault/10-projects/errors/webmvctest-slice-configprops-enum-placeholder-no-default-2026-06-20.md create mode 100644 vault/10-projects/invest-money-flow-system/project-notes/invest-money-flow-system.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-account-linking-spa-ux.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-account-linking-sub-vs-email.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-bff-csrf-samesite-defense.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-bff-oauth2login-session.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-bff-vs-spa-direct.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-docker-compose-stack.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-edge-forwardauth-google-federation.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-edge-forwardauth-no-google.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-federation-spa-zero-change.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-first-broker-login-flow.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-four-pattern-tradeoff-matrix.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-google-claim-attribute-mapping.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-google-redirect-uri-policy.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-header-spoofing-defense.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-https-termination-caddy-nginx.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-idp-brokering-google-client.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-idp-mappers-claim-to-role.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-internal-spa-direct-google-federation.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-internal-spa-direct-no-google.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-iss-claim-hostname-mismatch.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-nginx-auth-request-integration.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-oauth2-proxy-oidc-flow.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-patterns.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-pkce-flow-stages.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-public-domain-tunneling.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-realm-client-export.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-refresh-rotation-and-logout.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-refresh-token-rotation.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-reverse-proxy-headers.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-single-ec2-google-federation.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-single-ec2-no-google.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-spa-token-storage-tradeoff.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-spring-rs-audience-validator.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-spring-rs-role-mapping.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-three-leg-trust-chain.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-traefik-forwardauth-alternative.md create mode 100644 vault/10-projects/keycloak-patterns-overview/branch-notes/feature-keycloak-vanilla-js-spa-pkce.md create mode 100644 vault/10-projects/keycloak-patterns-overview/project-notes/keycloak-patterns-overview.md create mode 100644 vault/10-projects/llm-wiki-server-migration/project-notes/llm-wiki-server-migration.md create mode 100644 vault/10-projects/nplus1-presentation-prep/branch-notes/experiment-nplus1-feed-api-replay.md create mode 100644 vault/10-projects/nplus1-presentation-prep/branch-notes/experiment-nplus1-highlight-feed.md create mode 100644 vault/10-projects/nplus1-presentation-prep/project-notes/nplus1-presentation-prep.md create mode 100644 vault/10-projects/project-infra-overview/project-notes/project-infra-overview.md create mode 100644 vault/20-evidence/.gitkeep create mode 100644 vault/20-evidence/company-tech-blogs/adapter-togglz-ff4j-feature-toggle-library.md create mode 100644 vault/20-evidence/company-tech-blogs/api-versioning-github-rest-date-header.md create mode 100644 vault/20-evidence/company-tech-blogs/api-versioning-stripe-date-based.md create mode 100644 vault/20-evidence/company-tech-blogs/arhohuttunen-hexagonal-architecture-spring-boot.md create mode 100644 vault/20-evidence/company-tech-blogs/aws-iam-arn-format.md create mode 100644 vault/20-evidence/company-tech-blogs/axonframework-transactionmanager-spring-adapter.md create mode 100644 vault/20-evidence/company-tech-blogs/brandur-stripe-idempotency-keys.md create mode 100644 vault/20-evidence/company-tech-blogs/buckpal-archunit-lombok-allowlist-direct-transactional.md create mode 100644 vault/20-evidence/company-tech-blogs/cache-woowahan-after-commit-invalidation.md create mode 100644 vault/20-evidence/company-tech-blogs/ci-flaky-test-quarantine-spotify-google.md create mode 100644 vault/20-evidence/company-tech-blogs/config-launchdarkly-feature-flag-best-practice.md create mode 100644 vault/20-evidence/company-tech-blogs/container-woowahan-spring-native-tradeoffs.md create mode 100644 vault/20-evidence/company-tech-blogs/cqrs-lite-clean-architecture-read-path-bypass-wakita.md create mode 100644 vault/20-evidence/company-tech-blogs/curity-bff-pattern-spa.md create mode 100644 vault/20-evidence/company-tech-blogs/curity-oauth2-scope-vs-permission-naming.md create mode 100644 vault/20-evidence/company-tech-blogs/custom-transaction-interceptor-catnipcoder.md create mode 100644 vault/20-evidence/company-tech-blogs/deliberate-practice-software-developers-redgreencode.md create mode 100644 vault/20-evidence/company-tech-blogs/domain-event-sourcing-vs-cqrs-greg-young.md create mode 100644 vault/20-evidence/company-tech-blogs/domain-woowahan-ddd-aggregate-techblog.md create mode 100644 vault/20-evidence/company-tech-blogs/explicit-architecture-ddd-hexagonal-cqrs-hgraca.md create mode 100644 vault/20-evidence/company-tech-blogs/feature-first-sahibinden-package-by-layer-vs-feature.md create mode 100644 vault/20-evidence/company-tech-blogs/file-clamav-icap-gateway-scan.md create mode 100644 vault/20-evidence/company-tech-blogs/github-api-error-format.md create mode 100644 vault/20-evidence/company-tech-blogs/github-graphql-global-node-id.md create mode 100644 vault/20-evidence/company-tech-blogs/hexagonal-reflectoring-transactional-placement.md create mode 100644 vault/20-evidence/company-tech-blogs/hexagonal-woowahan-techblog-2023.md create mode 100644 vault/20-evidence/company-tech-blogs/idempotency-brandur-stripe-postgres.md create mode 100644 vault/20-evidence/company-tech-blogs/idempotency-redis-vs-db-storage.md create mode 100644 vault/20-evidence/company-tech-blogs/idempotency-toss-payments-techblog.md create mode 100644 vault/20-evidence/company-tech-blogs/jwks-workos-unknown-kid-refresh-rate-limit-pattern.md create mode 100644 vault/20-evidence/company-tech-blogs/keycloak-google-login-codemancers.md create mode 100644 vault/20-evidence/company-tech-blogs/keycloak-jwt-role-extraction-betweendata.md create mode 100644 vault/20-evidence/company-tech-blogs/layer-first-kamilmazurek-github-template.md create mode 100644 vault/20-evidence/company-tech-blogs/lock-subskribe-advisory-lock-distributed-consensus.md create mode 100644 vault/20-evidence/company-tech-blogs/metric-toss-payments-alert-severity-techblog.md create mode 100644 vault/20-evidence/company-tech-blogs/micrometer-context-propagation-line-be-hase.md create mode 100644 vault/20-evidence/company-tech-blogs/modulith-arawn-github-modular-monoliths-spring.md create mode 100644 vault/20-evidence/company-tech-blogs/modulith-kakaobank-techblog-2025.md create mode 100644 vault/20-evidence/company-tech-blogs/multitenancy-atlassian-tenant-context.md create mode 100644 vault/20-evidence/company-tech-blogs/multitenancy-auth0-tenant-resolution.md create mode 100644 vault/20-evidence/company-tech-blogs/multitenancy-hybrid-pooled-siloed-mix.md create mode 100644 vault/20-evidence/company-tech-blogs/multitenancy-stripe-citus-schema-per-tenant.md create mode 100644 vault/20-evidence/company-tech-blogs/multitenancy-subdomain-resolution-patterns.md create mode 100644 vault/20-evidence/company-tech-blogs/netflix-tudum-cqrs-separate-read-store-evolution.md create mode 100644 vault/20-evidence/company-tech-blogs/onion-allegro-tech-blog-2023.md create mode 100644 vault/20-evidence/company-tech-blogs/outbound-stripe-rate-limit-retry-engineering.md create mode 100644 vault/20-evidence/company-tech-blogs/outbox-confluent-kafka-connect-smt.md create mode 100644 vault/20-evidence/company-tech-blogs/outbox-netflix-domain-events-cdc.md create mode 100644 vault/20-evidence/company-tech-blogs/outbox-wix-engineering-debezium.md create mode 100644 vault/20-evidence/company-tech-blogs/outbox-woowahan-techblog-pattern.md create mode 100644 vault/20-evidence/company-tech-blogs/percona-uuid-storage-mysql.md create mode 100644 vault/20-evidence/company-tech-blogs/planetscale-nanoid-api.md create mode 100644 vault/20-evidence/company-tech-blogs/postgresql-slow-query-logging-crunchydata.md create mode 100644 vault/20-evidence/company-tech-blogs/privacy-pseudonymization-hmac-vs-tokenization-iapp.md create mode 100644 vault/20-evidence/company-tech-blogs/read-only-tx-hibernate-optimization-vladmihalcea.md create mode 100644 vault/20-evidence/company-tech-blogs/realtime-service-experience-woowahan-websocket.md create mode 100644 vault/20-evidence/company-tech-blogs/retry-aws-exponential-backoff-and-jitter.md create mode 100644 vault/20-evidence/company-tech-blogs/runbook-atlassian-gitops-runbook-as-code.md create mode 100644 vault/20-evidence/company-tech-blogs/runbook-woowahan-incident-techblog.md create mode 100644 vault/20-evidence/company-tech-blogs/runtime-health-datadog-engineering-graceful-shutdown.md create mode 100644 vault/20-evidence/company-tech-blogs/scaffolding-backstage-golden-path-spotify.md create mode 100644 vault/20-evidence/company-tech-blogs/scoped-value-structured-concurrency-softwaremill.md create mode 100644 vault/20-evidence/company-tech-blogs/secrets-1password-developer-secret-references.md create mode 100644 vault/20-evidence/company-tech-blogs/security-toss-actuator-healthcheck.md create mode 100644 vault/20-evidence/company-tech-blogs/security-woowahan-actuator-safe-usage.md create mode 100644 vault/20-evidence/company-tech-blogs/segment-ksuid.md create mode 100644 vault/20-evidence/company-tech-blogs/senior-engineer-competency-mubin-shaikh.md create mode 100644 vault/20-evidence/company-tech-blogs/skillable-hands-on-lab-structure.md create mode 100644 vault/20-evidence/company-tech-blogs/slow-query-datasource-proxy-spring-boot-galovics.md create mode 100644 vault/20-evidence/company-tech-blogs/snowflake-twitter-id.md create mode 100644 vault/20-evidence/company-tech-blogs/spring-modulith-archunit-generated-exemption-and-violations-as-data.md create mode 100644 vault/20-evidence/company-tech-blogs/sse-realtime-notification-woowahan.md create mode 100644 vault/20-evidence/company-tech-blogs/stripe-error-format.md create mode 100644 vault/20-evidence/company-tech-blogs/test-pyramid-vs-trophy-kent-dodds.md create mode 100644 vault/20-evidence/company-tech-blogs/thorben-janssen-hibernate-timestamp-clock-limitation.md create mode 100644 vault/20-evidence/company-tech-blogs/threadlocal-capture-restore-att-israel.md create mode 100644 vault/20-evidence/company-tech-blogs/toss-payments-error-format.md create mode 100644 vault/20-evidence/company-tech-blogs/tracing-datadog-apm-vs-opentelemetry.md create mode 100644 vault/20-evidence/company-tech-blogs/transaction-port-clean-ddd-spring-medium.md create mode 100644 vault/20-evidence/company-tech-blogs/transaction-port-vassilis-soum-github-readme.md create mode 100644 vault/20-evidence/company-tech-blogs/vlad-mihalcea-postgresql-audit-logging-triggers.md create mode 100644 vault/20-evidence/company-tech-blogs/woowahan-hexagonal-multimodule.md create mode 100644 vault/20-evidence/invest-research/2026-06-05-passive-diversification-behavior.md create mode 100644 vault/20-evidence/invest-research/2026-06-05-stoploss-takeprofit-tax-accounts.md create mode 100644 vault/20-evidence/invest-research/2026-06-08-broad-equity-etf-100man-candidates.md create mode 100644 vault/20-evidence/invest-research/2026-06-08-isa-vs-general-account-no-income.md create mode 100644 vault/20-evidence/invest-research/2026-06-08-korean-broad-etf-ticker-comparison.md create mode 100644 vault/20-evidence/official-docs/actuator-endpoint-exposure-spring-official.md create mode 100644 vault/20-evidence/official-docs/actuator-istio-sidecar-management-alt.md create mode 100644 vault/20-evidence/official-docs/actuator-management-port-spring-official.md create mode 100644 vault/20-evidence/official-docs/adapter-java-spi-serviceloader.md create mode 100644 vault/20-evidence/official-docs/adapter-spring-boot-autoconfig-custom-starter.md create mode 100644 vault/20-evidence/official-docs/api-versioning-google-aip-180.md create mode 100644 vault/20-evidence/official-docs/arch-acl-microsoft-pattern.md create mode 100644 vault/20-evidence/official-docs/arch-clean-architecture-uncle-bob.md create mode 100644 vault/20-evidence/official-docs/arch-hexagonal-cockburn.md create mode 100644 vault/20-evidence/official-docs/archunit-annotation-as-registry-evaluation.md create mode 100644 vault/20-evidence/official-docs/archunit-conditional-on-property-3-layer-pattern.md create mode 100644 vault/20-evidence/official-docs/archunit-user-guide.md create mode 100644 vault/20-evidence/official-docs/at-transactional-spring-official.md create mode 100644 vault/20-evidence/official-docs/aws-acm-managed-renewal.md create mode 100644 vault/20-evidence/official-docs/aws-alb-target-security-group-restriction-official.md create mode 100644 vault/20-evidence/official-docs/aws-builders-retry-jitter.md create mode 100644 vault/20-evidence/official-docs/aws-cloudfront-origin-shared-secret-header-official.md create mode 100644 vault/20-evidence/official-docs/aws-iam-google-iam-permission-naming-convention.md create mode 100644 vault/20-evidence/official-docs/aws-security-group-referencing-official.md create mode 100644 vault/20-evidence/official-docs/baggage-otel-baggage-api-spec.md create mode 100644 vault/20-evidence/official-docs/baggage-w3c-baggage-spec.md create mode 100644 vault/20-evidence/official-docs/cache-aside-vs-write-through-aws.md create mode 100644 vault/20-evidence/official-docs/cache-caffeine-asyncloadingcache-readme.md create mode 100644 vault/20-evidence/official-docs/cache-redisson-rlock-vs-setnx.md create mode 100644 vault/20-evidence/official-docs/caddy-automatic-https-docs.md create mode 100644 vault/20-evidence/official-docs/calver-spec-calver-official.md create mode 100644 vault/20-evidence/official-docs/certbot-user-guide.md create mode 100644 vault/20-evidence/official-docs/checkstyle-google-style-reference.md create mode 100644 vault/20-evidence/official-docs/chrome-third-party-cookie-policy-google-official.md create mode 100644 vault/20-evidence/official-docs/ci-github-actions-vs-gitlab-comparison.md create mode 100644 vault/20-evidence/official-docs/ci-openapi-snapshot-diff-tooling.md create mode 100644 vault/20-evidence/official-docs/cloudevents-spec-required-attributes.md create mode 100644 vault/20-evidence/official-docs/cloudflare-tunnel-routing-official.md create mode 100644 vault/20-evidence/official-docs/compat-rfc-8594-sunset-header.md create mode 100644 vault/20-evidence/official-docs/config-12-factor-app-config.md create mode 100644 vault/20-evidence/official-docs/config-aws-appconfig-feature-flag-deployment.md create mode 100644 vault/20-evidence/official-docs/config-spring-boot-externalized-configuration.md create mode 100644 vault/20-evidence/official-docs/config-spring-cloud-config-server-official.md create mode 100644 vault/20-evidence/official-docs/config-spring-cloud-kubernetes-configmap-reload.md create mode 100644 vault/20-evidence/official-docs/container-alpine-java-musl-tradeoffs.md create mode 100644 vault/20-evidence/official-docs/container-distroless-google-github.md create mode 100644 vault/20-evidence/official-docs/container-graalvm-native-image-spring-boot.md create mode 100644 vault/20-evidence/official-docs/container-stdout-logging-12factor-official.md create mode 100644 vault/20-evidence/official-docs/cosign-keyless-identity-verification-policy.md create mode 100644 vault/20-evidence/official-docs/cqrs-fowler-bliki.md create mode 100644 vault/20-evidence/official-docs/cqrs-pattern-azure-architecture-center.md create mode 100644 vault/20-evidence/official-docs/crockford-base32-spec.md create mode 100644 vault/20-evidence/official-docs/cuid2-spec.md create mode 100644 vault/20-evidence/official-docs/datasource-micrometer-observation-official.md create mode 100644 vault/20-evidence/official-docs/datasource-proxy-slow-query-official.md create mode 100644 vault/20-evidence/official-docs/dependabot-security-updates-gradle-official.md create mode 100644 vault/20-evidence/official-docs/dependabot-supported-ecosystems-official.md create mode 100644 vault/20-evidence/official-docs/docker-compose-depends-on-healthcheck.md create mode 100644 vault/20-evidence/official-docs/docker-compose-networking-extra-hosts-official.md create mode 100644 vault/20-evidence/official-docs/docker-engine-20-10-release-notes-official.md create mode 100644 vault/20-evidence/official-docs/docker-host-network-driver-official.md create mode 100644 vault/20-evidence/official-docs/docker-port-publishing-loopback-bind-official.md create mode 100644 vault/20-evidence/official-docs/domain-event-fowler-eaa.md create mode 100644 vault/20-evidence/official-docs/domain-fowler-anemic-vs-rich-model.md create mode 100644 vault/20-evidence/official-docs/domain-vaughn-vernon-aggregate-root.md create mode 100644 vault/20-evidence/official-docs/dual-write-antipattern-microservices-io.md create mode 100644 vault/20-evidence/official-docs/dx-devcontainer-spring-boot.md create mode 100644 vault/20-evidence/official-docs/dx-mise-asdf-tool-versioning.md create mode 100644 vault/20-evidence/official-docs/dx-testcontainers-java-best-practices.md create mode 100644 vault/20-evidence/official-docs/ecs-awslogs-stdout-cloudwatch-aws-official.md create mode 100644 vault/20-evidence/official-docs/errorprone-gradle-plugin-readme.md create mode 100644 vault/20-evidence/official-docs/event-sourcing-vs-outbox-microservices-io.md create mode 100644 vault/20-evidence/official-docs/feature-first-uncle-bob-screaming-architecture-2011.md create mode 100644 vault/20-evidence/official-docs/fetch-spec-cors.md create mode 100644 vault/20-evidence/official-docs/file-s3-presigned-url-upload.md create mode 100644 vault/20-evidence/official-docs/file-tus-resumable-upload-protocol.md create mode 100644 vault/20-evidence/official-docs/find-sec-bugs-official.md create mode 100644 vault/20-evidence/official-docs/functional-tx-arrow-kt-resource-docs.md create mode 100644 vault/20-evidence/official-docs/gdpr-cryptographic-erasure-envelope-key-pattern.md create mode 100644 vault/20-evidence/official-docs/github-dependency-review-action.md create mode 100644 vault/20-evidence/official-docs/github-webhook-signature.md create mode 100644 vault/20-evidence/official-docs/google-aip-122-resource-names.md create mode 100644 vault/20-evidence/official-docs/google-aip-127-http-transcoding.md create mode 100644 vault/20-evidence/official-docs/google-aip-132-list-method.md create mode 100644 vault/20-evidence/official-docs/google-aip-136-custom-methods.md create mode 100644 vault/20-evidence/official-docs/google-aip-148-standard-fields.md create mode 100644 vault/20-evidence/official-docs/google-aip-151-long-running-operations.md create mode 100644 vault/20-evidence/official-docs/google-aip-158-pagination.md create mode 100644 vault/20-evidence/official-docs/google-aip-160-filtering.md create mode 100644 vault/20-evidence/official-docs/google-aip-185-resource-versioning.md create mode 100644 vault/20-evidence/official-docs/google-aip-233-batch-create.md create mode 100644 vault/20-evidence/official-docs/google-antigravity-hooks.md create mode 100644 vault/20-evidence/official-docs/google-api-error-format.md create mode 100644 vault/20-evidence/official-docs/google-java-format-readme.md create mode 100644 vault/20-evidence/official-docs/google-oauth-app-verification-state-overview-official.md create mode 100644 vault/20-evidence/official-docs/google-oauth-manage-app-audience-official.md create mode 100644 vault/20-evidence/official-docs/google-oauth2-client-application-types-official.md create mode 100644 vault/20-evidence/official-docs/google-oauth2-policies-environment-separation-official.md create mode 100644 vault/20-evidence/official-docs/google-oauth2-redirect-uri-validation-official.md create mode 100644 vault/20-evidence/official-docs/google-oauth2-web-server-flow-official.md create mode 100644 vault/20-evidence/official-docs/google-oidc-discovery-spec.md create mode 100644 vault/20-evidence/official-docs/google-openid-connect-oidc.md create mode 100644 vault/20-evidence/official-docs/google-sre-workbook-on-call-monitoring.md create mode 100644 vault/20-evidence/official-docs/governance-archunit-official.md create mode 100644 vault/20-evidence/official-docs/gradle-java-library-api-vs-implementation.md create mode 100644 vault/20-evidence/official-docs/gradle-reproducible-archives-working-with-files.md create mode 100644 vault/20-evidence/official-docs/graphql-errors-spec.md create mode 100644 vault/20-evidence/official-docs/hexagonal-cockburn-wikipedia-summary.md create mode 100644 vault/20-evidence/official-docs/hexagonal-thombergs-buckpal-github.md create mode 100644 vault/20-evidence/official-docs/hibernate-slow-query-log-official.md create mode 100644 vault/20-evidence/official-docs/iana-media-types-registry.md create mode 100644 vault/20-evidence/official-docs/idempotency-aws-lambda-powertools.md create mode 100644 vault/20-evidence/official-docs/idempotency-ietf-draft.md create mode 100644 vault/20-evidence/official-docs/idempotency-no-api-level-github-rest.md create mode 100644 vault/20-evidence/official-docs/idempotency-paypal-docs.md create mode 100644 vault/20-evidence/official-docs/idempotency-square-api.md create mode 100644 vault/20-evidence/official-docs/idempotency-stripe-api-ref.md create mode 100644 vault/20-evidence/official-docs/istio-mtls-cert-rotation-official.md create mode 100644 vault/20-evidence/official-docs/jdk-files-createtempfile.md create mode 100644 vault/20-evidence/official-docs/jdk21-threadpoolexecutor-javadoc.md create mode 100644 vault/20-evidence/official-docs/json-api-errors-spec.md create mode 100644 vault/20-evidence/official-docs/jsonapi-pagination-format.md create mode 100644 vault/20-evidence/official-docs/junit5-conditional-env-variable-user-guide.md create mode 100644 vault/20-evidence/official-docs/jwks-keycloak-key-rotation-active-passive.md create mode 100644 vault/20-evidence/official-docs/jwks-nimbus-jose-jwksourcebuilder-spring-integration.md create mode 100644 vault/20-evidence/official-docs/k8s-application-security-checklist-readonly-fs.md create mode 100644 vault/20-evidence/official-docs/k8s-configure-probes-task-page.md create mode 100644 vault/20-evidence/official-docs/k8s-logging-architecture-kubernetes-official.md create mode 100644 vault/20-evidence/official-docs/k8s-network-policy-official.md create mode 100644 vault/20-evidence/official-docs/k8s-pod-lifecycle-probes-concept.md create mode 100644 vault/20-evidence/official-docs/k8s-pod-security-standards-restricted.md create mode 100644 vault/20-evidence/official-docs/keycloak-2500-hostname-v2-release-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-2600-hostname-v1-removed-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-account-console-unlink-lockout-guard-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-authorization-services-realm-client-roles.md create mode 100644 vault/20-evidence/official-docs/keycloak-client-initiated-account-linking.md create mode 100644 vault/20-evidence/official-docs/keycloak-client-pkce-method-enforcement-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-configuring-database.md create mode 100644 vault/20-evidence/official-docs/keycloak-first-broker-login-flow.md create mode 100644 vault/20-evidence/official-docs/keycloak-first-broker-login-verify-authenticators-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-first-login-flow.md create mode 100644 vault/20-evidence/official-docs/keycloak-getting-started-docker.md create mode 100644 vault/20-evidence/official-docs/keycloak-google-idp-setup.md create mode 100644 vault/20-evidence/official-docs/keycloak-health-checks.md create mode 100644 vault/20-evidence/official-docs/keycloak-hostname-configuration.md create mode 100644 vault/20-evidence/official-docs/keycloak-identity-broker-spi.md create mode 100644 vault/20-evidence/official-docs/keycloak-identity-brokering-overview-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-identity-provider-mappers.md create mode 100644 vault/20-evidence/official-docs/keycloak-identity-provider-redirector-default-idp-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-identity-provider-sync-mode-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-identity-provider-trust-email-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-idp-hide-on-login-page-toggle-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-idp-hint-client-suggested-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-import-export-realms.md create mode 100644 vault/20-evidence/official-docs/keycloak-oidc-logout-endpoint-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-refresh-token-rotation-reuse-admin-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-refresh-token-rotation-sessions-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-reverseproxy-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-securing-apps-overview-official.md create mode 100644 vault/20-evidence/official-docs/keycloak-server-containers-docker.md create mode 100644 vault/20-evidence/official-docs/kubernetes-exit-code-observability-termination.md create mode 100644 vault/20-evidence/official-docs/kubernetes-pod-lifecycle-termination.md create mode 100644 vault/20-evidence/official-docs/layer-first-baeldung-clean-architecture-spring-boot.md create mode 100644 vault/20-evidence/official-docs/lock-postgres-advisory-locks.md create mode 100644 vault/20-evidence/official-docs/lock-shedlock-issue-899-non-scheduler-use.md create mode 100644 vault/20-evidence/official-docs/lock-shedlock-readme.md create mode 100644 vault/20-evidence/official-docs/lock-spring-integration-lock-registry.md create mode 100644 vault/20-evidence/official-docs/log-ecs-schema-elastic-official.md create mode 100644 vault/20-evidence/official-docs/log-logback-mask-pattern-converter-official.md create mode 100644 vault/20-evidence/official-docs/log-otel-log-data-model-spec.md create mode 100644 vault/20-evidence/official-docs/lombok-builder-data-features-official.md create mode 100644 vault/20-evidence/official-docs/lychee-link-checker.md create mode 100644 vault/20-evidence/official-docs/mapstruct-generated-annotation-official.md create mode 100644 vault/20-evidence/official-docs/metric-google-ewaschuk-philosophy-on-alerting.md create mode 100644 vault/20-evidence/official-docs/metric-google-sre-slo-burn-rate.md create mode 100644 vault/20-evidence/official-docs/metric-google-sre-workbook-on-call.md create mode 100644 vault/20-evidence/official-docs/metric-micrometer-high-cardinality-tags-detector.md create mode 100644 vault/20-evidence/official-docs/metric-micrometer-histogram-percentile-concepts.md create mode 100644 vault/20-evidence/official-docs/metric-micrometer-naming-convention-official.md create mode 100644 vault/20-evidence/official-docs/metric-otel-metrics-data-model-spec.md create mode 100644 vault/20-evidence/official-docs/metric-prometheus-histograms-vs-summaries-practices.md create mode 100644 vault/20-evidence/official-docs/metric-prometheus-label-cardinality-best-practices.md create mode 100644 vault/20-evidence/official-docs/micrometer-context-propagation-official.md create mode 100644 vault/20-evidence/official-docs/micrometer-context-propagation-purpose-thread-local-accessor.md create mode 100644 vault/20-evidence/official-docs/microservices-io-transactional-outbox.md create mode 100644 vault/20-evidence/official-docs/migration-atlas-schema-as-code.md create mode 100644 vault/20-evidence/official-docs/migration-flyway-official-concepts-and-repair.md create mode 100644 vault/20-evidence/official-docs/migration-k8s-init-container-job-pattern.md create mode 100644 vault/20-evidence/official-docs/migration-liquibase-official-changelog-xml-yaml.md create mode 100644 vault/20-evidence/official-docs/modulith-spring-official-doc.md create mode 100644 vault/20-evidence/official-docs/multitenancy-aws-saas-tenant-isolation-whitepaper.md create mode 100644 vault/20-evidence/official-docs/multitenancy-azure-architecture-patterns.md create mode 100644 vault/20-evidence/official-docs/multitenancy-hibernate-user-guide.md create mode 100644 vault/20-evidence/official-docs/multitenancy-microservices-io-pattern.md create mode 100644 vault/20-evidence/official-docs/mysql-innodb-transaction-isolation-official.md create mode 100644 vault/20-evidence/official-docs/nanoid-spec.md create mode 100644 vault/20-evidence/official-docs/nginx-auth-request-module-official.md create mode 100644 vault/20-evidence/official-docs/nginx-client-max-body-size.md create mode 100644 vault/20-evidence/official-docs/nginx-core-module-location-internal-official.md create mode 100644 vault/20-evidence/official-docs/ngrok-http-tunnel-official.md create mode 100644 vault/20-evidence/official-docs/oauth-v2-1-draft-ietf.md create mode 100644 vault/20-evidence/official-docs/oauth2-browser-based-apps-ietf-draft.md create mode 100644 vault/20-evidence/official-docs/oauth2-pkce-rfc-7636.md create mode 100644 vault/20-evidence/official-docs/oauth2-proxy-behaviour-cookie-vs-bearer-official.md create mode 100644 vault/20-evidence/official-docs/oauth2-proxy-cookie-redirect-flags-official.md create mode 100644 vault/20-evidence/official-docs/oauth2-proxy-endpoints-official.md create mode 100644 vault/20-evidence/official-docs/oauth2-proxy-endpoints-signout-official.md create mode 100644 vault/20-evidence/official-docs/oauth2-proxy-keycloak-oidc-provider-official.md create mode 100644 vault/20-evidence/official-docs/oauth2-proxy-nginx-integration-official.md create mode 100644 vault/20-evidence/official-docs/oauth2-proxy-overview-config-official.md create mode 100644 vault/20-evidence/official-docs/oauth2-proxy-session-storage-official.md create mode 100644 vault/20-evidence/official-docs/oauth2-token-revocation-rfc-7009.md create mode 100644 vault/20-evidence/official-docs/oidc-client-ts-library.md create mode 100644 vault/20-evidence/official-docs/onion-palermo-original-2008.md create mode 100644 vault/20-evidence/official-docs/openapi-spec-3-1-0.md create mode 100644 vault/20-evidence/official-docs/openid-connect-core-id-token-validation.md create mode 100644 vault/20-evidence/official-docs/openjdk-jdk-8196595-container-support.md create mode 100644 vault/20-evidence/official-docs/opentelemetry-http-semconv-migration-guide.md create mode 100644 vault/20-evidence/official-docs/opentelemetry-versioning-stability-spec.md create mode 100644 vault/20-evidence/official-docs/otel-exceptions-semantic-conventions.md create mode 100644 vault/20-evidence/official-docs/outbound-openfeign-declarative-client.md create mode 100644 vault/20-evidence/official-docs/outbound-resilience4j-vs-spring-retry.md create mode 100644 vault/20-evidence/official-docs/outbound-spring-restclient-baseline.md create mode 100644 vault/20-evidence/official-docs/outbound-webclient-vs-restclient-spring.md create mode 100644 vault/20-evidence/official-docs/outbox-debezium-official-docs.md create mode 100644 vault/20-evidence/official-docs/outbox-skip-locked-microservices-io.md create mode 100644 vault/20-evidence/official-docs/owasp-authz-permission-model-abac-rbac.md create mode 100644 vault/20-evidence/official-docs/owasp-content-security-policy-cheat-sheet.md create mode 100644 vault/20-evidence/official-docs/owasp-file-upload-cheat-sheet.md create mode 100644 vault/20-evidence/official-docs/owasp-hsts-cheat-sheet.md create mode 100644 vault/20-evidence/official-docs/owasp-html5-storage-xss-spa.md create mode 100644 vault/20-evidence/official-docs/owasp-logging-cheat-sheet.md create mode 100644 vault/20-evidence/official-docs/owasp-path-traversal.md create mode 100644 vault/20-evidence/official-docs/owasp-ssrf-prevention.md create mode 100644 vault/20-evidence/official-docs/p6spy-configuration-official.md create mode 100644 vault/20-evidence/official-docs/patch-json-merge-rfc7396.md create mode 100644 vault/20-evidence/official-docs/persistence-hikaricp-configuration-knobs.md create mode 100644 vault/20-evidence/official-docs/persistence-hikaricp-pool-sizing-wiki.md create mode 100644 vault/20-evidence/official-docs/persistence-osiv-antipattern-hibernate-vladmihalcea.md create mode 100644 vault/20-evidence/official-docs/persistence-r2dbc-reactive-spring.md create mode 100644 vault/20-evidence/official-docs/persistence-spring-dataaccessexception-hierarchy.md create mode 100644 vault/20-evidence/official-docs/postgres-transaction-isolation-official.md create mode 100644 vault/20-evidence/official-docs/postgresql-slow-query-log-official.md create mode 100644 vault/20-evidence/official-docs/privacy-cryptographic-erasure-nist-sp800-88.md create mode 100644 vault/20-evidence/official-docs/privacy-gdpr-article-25-design.md create mode 100644 vault/20-evidence/official-docs/problem-detail-rfc-7807.md create mode 100644 vault/20-evidence/official-docs/prometheus-alertmanager-silences.md create mode 100644 vault/20-evidence/official-docs/protobuf-reserved-vs-json-openapi-extension.md create mode 100644 vault/20-evidence/official-docs/proxy-pass-request-body-nginx-official.md create mode 100644 vault/20-evidence/official-docs/react-router-official.md create mode 100644 vault/20-evidence/official-docs/react-ui-library-official.md create mode 100644 vault/20-evidence/official-docs/redhat-openjdk-container-awareness-java17.md create mode 100644 vault/20-evidence/official-docs/registry-adr-official.md create mode 100644 vault/20-evidence/official-docs/renovate-gradle-manager-official.md create mode 100644 vault/20-evidence/official-docs/renovate-vulnerability-alerts-gradle-official.md create mode 100644 vault/20-evidence/official-docs/reproducible-builds-org-jvm-guide.md create mode 100644 vault/20-evidence/official-docs/resilience4j-micrometer-module.md create mode 100644 vault/20-evidence/official-docs/retry-aws-well-architected-rel05-bp03.md create mode 100644 vault/20-evidence/official-docs/retry-spring-retry-readme-backoff-defaults.md create mode 100644 vault/20-evidence/official-docs/rfc3339-datetime-utc.md create mode 100644 vault/20-evidence/official-docs/rfc3986-uri-generic-syntax.md create mode 100644 vault/20-evidence/official-docs/rfc6455-websocket.md create mode 100644 vault/20-evidence/official-docs/rfc8996-tls10-tls11-deprecation.md create mode 100644 vault/20-evidence/official-docs/rfc9110-http-semantics.md create mode 100644 vault/20-evidence/official-docs/rfc9111-http-caching.md create mode 100644 vault/20-evidence/official-docs/rfc9112-http-1-1-chunked-transfer.md create mode 100644 vault/20-evidence/official-docs/rfc9421-http-message-signatures.md create mode 100644 vault/20-evidence/official-docs/rfc9457-problem-details-http-apis.md create mode 100644 vault/20-evidence/official-docs/rfc9562-uuid.md create mode 100644 vault/20-evidence/official-docs/runbook-pagerduty-incident-response-doc.md create mode 100644 vault/20-evidence/official-docs/runtime-health-istio-mesh-health-check.md create mode 100644 vault/20-evidence/official-docs/runtime-health-k8s-probes-official.md create mode 100644 vault/20-evidence/official-docs/runtime-health-spring-actuator-groups.md create mode 100644 vault/20-evidence/official-docs/runtime-spring-boot-virtual-threads.md create mode 100644 vault/20-evidence/official-docs/sample-microservices-spring-cloud-github.md create mode 100644 vault/20-evidence/official-docs/sample-realworld-gothinkster-github.md create mode 100644 vault/20-evidence/official-docs/sample-spring-petclinic-github.md create mode 100644 vault/20-evidence/official-docs/scaffolding-cookiecutter-official.md create mode 100644 vault/20-evidence/official-docs/scaffolding-degit-svelte-github.md create mode 100644 vault/20-evidence/official-docs/scaffolding-github-template-repository.md create mode 100644 vault/20-evidence/official-docs/scaffolding-spring-initializr.md create mode 100644 vault/20-evidence/official-docs/schema-avro-evolution-rules.md create mode 100644 vault/20-evidence/official-docs/schema-bigdecimal-money-serialization-java.md create mode 100644 vault/20-evidence/official-docs/schema-jackson-polymorphic-deserialization.md create mode 100644 vault/20-evidence/official-docs/schema-jackson-unknown-field-handling.md create mode 100644 vault/20-evidence/official-docs/schema-protobuf-vs-json-evolution.md create mode 100644 vault/20-evidence/official-docs/scoped-value-jep-446-506-openjdk.md create mode 100644 vault/20-evidence/official-docs/scorecard-aws-well-architected.md create mode 100644 vault/20-evidence/official-docs/scorecard-cis-benchmarks-slsa.md create mode 100644 vault/20-evidence/official-docs/scorecard-opentelemetry-maturity.md create mode 100644 vault/20-evidence/official-docs/secrets-aws-secrets-manager-rotation.md create mode 100644 vault/20-evidence/official-docs/secrets-k8s-secret-external-secrets-operator.md create mode 100644 vault/20-evidence/official-docs/secrets-vault-dynamic-secrets-hashicorp.md create mode 100644 vault/20-evidence/official-docs/security-authorization-cheatsheet-owasp.md create mode 100644 vault/20-evidence/official-docs/security-aws-sigv4-hmac-signing.md create mode 100644 vault/20-evidence/official-docs/security-jwt-rfc-7519-validation.md create mode 100644 vault/20-evidence/official-docs/security-mtls-rfc-8705.md create mode 100644 vault/20-evidence/official-docs/security-oauth2-pkce-rfc-8252.md create mode 100644 vault/20-evidence/official-docs/security-opa-policy-engine-official.md create mode 100644 vault/20-evidence/official-docs/security-spring-jwt-timestamp-validator-clock-skew.md create mode 100644 vault/20-evidence/official-docs/semver-2-0-0-spec-semver-official.md create mode 100644 vault/20-evidence/official-docs/silent-check-sso-third-party-cookies-keycloak-official.md create mode 100644 vault/20-evidence/official-docs/skip-locked-mysql-docs.md create mode 100644 vault/20-evidence/official-docs/skip-locked-postgres-docs.md create mode 100644 vault/20-evidence/official-docs/slsa-v1-provenance-schema.md create mode 100644 vault/20-evidence/official-docs/sonarqube-server-versus-cloud.md create mode 100644 vault/20-evidence/official-docs/spotbugs-gradle-plugin-docs.md create mode 100644 vault/20-evidence/official-docs/spotless-gradle-plugin-readme.md create mode 100644 vault/20-evidence/official-docs/spring-boot-exit-code-generator-startup-failure.md create mode 100644 vault/20-evidence/official-docs/spring-boot-graceful-shutdown-reference.md create mode 100644 vault/20-evidence/official-docs/spring-boot-multipart-reference.md create mode 100644 vault/20-evidence/official-docs/spring-boot-structuring-your-code.md create mode 100644 vault/20-evidence/official-docs/spring-boot-task-execution-scheduling-reference.md create mode 100644 vault/20-evidence/official-docs/spring-boot-test-slices-webmvctest-datajpatest-official.md create mode 100644 vault/20-evidence/official-docs/spring-data-jpa-auditing-official.md create mode 100644 vault/20-evidence/official-docs/spring-data-jpa-enable-jpa-auditing-api.md create mode 100644 vault/20-evidence/official-docs/spring-data-jpa-projections-spring-official.md create mode 100644 vault/20-evidence/official-docs/spring-data-jpa-transactionality-spring-official.md create mode 100644 vault/20-evidence/official-docs/spring-data-pageable-defaults.md create mode 100644 vault/20-evidence/official-docs/spring-executor-configuration-support-javadoc.md create mode 100644 vault/20-evidence/official-docs/spring-framework-observability-context-propagating-task-decorator.md create mode 100644 vault/20-evidence/official-docs/spring-framework-test-enabledif-jupiter-annotation.md create mode 100644 vault/20-evidence/official-docs/spring-framework-threadpooltaskexecutor-javadoc.md create mode 100644 vault/20-evidence/official-docs/spring-mvc-async-streaming.md create mode 100644 vault/20-evidence/official-docs/spring-mvc-rest-exception-handling.md create mode 100644 vault/20-evidence/official-docs/spring-problem-detail.md create mode 100644 vault/20-evidence/official-docs/spring-restclient-builder-reference.md create mode 100644 vault/20-evidence/official-docs/spring-security-authorization-architecture.md create mode 100644 vault/20-evidence/official-docs/spring-security-authorization-defense-in-depth.md create mode 100644 vault/20-evidence/official-docs/spring-security-authorize-http-requests.md create mode 100644 vault/20-evidence/official-docs/spring-security-concurrency-delegating-security-context-executor.md create mode 100644 vault/20-evidence/official-docs/spring-security-method-security.md create mode 100644 vault/20-evidence/official-docs/spring-security-nested-authorities-claim-issue-15201.md create mode 100644 vault/20-evidence/official-docs/spring-security-resource-server-jwt.md create mode 100644 vault/20-evidence/official-docs/spring-smartlifecycle-reference.md create mode 100644 vault/20-evidence/official-docs/spring-streaming-response-body.md create mode 100644 vault/20-evidence/official-docs/spring-transaction-synchronization-manager-javadoc.md create mode 100644 vault/20-evidence/official-docs/spring-transactional-event-listener.md create mode 100644 vault/20-evidence/official-docs/spring-tx-management-reference.md create mode 100644 vault/20-evidence/official-docs/spring-tx-propagation-required-new-nested-official.md create mode 100644 vault/20-evidence/official-docs/stripe-resource-id-convention.md create mode 100644 vault/20-evidence/official-docs/stripe-webhook-signature.md create mode 100644 vault/20-evidence/official-docs/sunset-deprecation-headers-paired-usage.md create mode 100644 vault/20-evidence/official-docs/supply-chain-cosign-keyless-sigstore.md create mode 100644 vault/20-evidence/official-docs/supply-chain-gradle-vs-maven-dependency-locking.md create mode 100644 vault/20-evidence/official-docs/supply-chain-slsa-provenance-framework.md create mode 100644 vault/20-evidence/official-docs/svix-webhook-best-practices.md create mode 100644 vault/20-evidence/official-docs/sysexits-bsd-exit-code-convention.md create mode 100644 vault/20-evidence/official-docs/tailwind-css-utility-first-official.md create mode 100644 vault/20-evidence/official-docs/tanstack-query-server-state-official.md create mode 100644 vault/20-evidence/official-docs/test-taxonomy-practical-pyramid-fowler.md create mode 100644 vault/20-evidence/official-docs/test-taxonomy-testcontainers-official.md create mode 100644 vault/20-evidence/official-docs/third-party-cookie-blocking-safari-webkit-official.md create mode 100644 vault/20-evidence/official-docs/threadlocal-virtual-threads-java21-oracle.md create mode 100644 vault/20-evidence/official-docs/trace-context-w3c-recommendation.md create mode 100644 vault/20-evidence/official-docs/tracing-b3-propagation-zipkin-spec.md create mode 100644 vault/20-evidence/official-docs/tracing-micrometer-observation-introduction.md create mode 100644 vault/20-evidence/official-docs/tracing-otel-sampling-tail-vs-head-spec.md create mode 100644 vault/20-evidence/official-docs/tracing-otel-trace-api-spec.md create mode 100644 vault/20-evidence/official-docs/tracing-spring-boot-3-actuator-tracing-reference.md create mode 100644 vault/20-evidence/official-docs/tracing-w3c-trace-context-spec.md create mode 100644 vault/20-evidence/official-docs/traefik-forwardauth-middleware-official.md create mode 100644 vault/20-evidence/official-docs/traefik-hub-oidc-middleware-official.md create mode 100644 vault/20-evidence/official-docs/traefik-oidc-community-plugin-lukaszraczylo-official.md create mode 100644 vault/20-evidence/official-docs/transaction-template-spring-official.md create mode 100644 vault/20-evidence/official-docs/transactional-outbox-aws-prescriptive-guidance.md create mode 100644 vault/20-evidence/official-docs/trivy-action-github-actions.md create mode 100644 vault/20-evidence/official-docs/trivy-filtering-suppression-policy.md create mode 100644 vault/20-evidence/official-docs/trivy-java-language-coverage.md create mode 100644 vault/20-evidence/official-docs/trivy-severity-exit-code-gating.md create mode 100644 vault/20-evidence/official-docs/ulid-spec.md create mode 100644 vault/20-evidence/official-docs/validation-jakarta-bean-validation-3.0-spec.md create mode 100644 vault/20-evidence/official-docs/verification-approvaltests-snapshot-official.md create mode 100644 vault/20-evidence/official-docs/verification-pact-cdc-official.md create mode 100644 vault/20-evidence/official-docs/verification-spring-cloud-contract-official.md create mode 100644 vault/20-evidence/official-docs/verification-spring-restdocs-official.md create mode 100644 vault/20-evidence/official-docs/vite-build-tool-official.md create mode 100644 vault/20-evidence/official-docs/vuln-severity-cisa-kev-catalog-official.md create mode 100644 vault/20-evidence/official-docs/vuln-severity-cvss-v31-spec-first-official.md create mode 100644 vault/20-evidence/official-docs/whatwg-html-server-sent-events.md create mode 100644 vault/20-evidence/official-docs/zod-runtime-schema-validation-official.md create mode 100644 vault/30-knowledge/.gitkeep create mode 100644 vault/30-knowledge/concepts/api-error-envelope-design.md create mode 100644 vault/30-knowledge/concepts/api-evolution-and-schema.md create mode 100644 vault/30-knowledge/concepts/archunit-scope-classpath-vs-package-filter.md create mode 100644 vault/30-knowledge/concepts/boundary-validation-and-dto-mapping.md create mode 100644 vault/30-knowledge/concepts/circuit-breaker.md create mode 100644 vault/30-knowledge/concepts/clean-architecture-package-layout.md create mode 100644 vault/30-knowledge/concepts/config-and-adapter-templates.md create mode 100644 vault/30-knowledge/concepts/data-layer-persistence-cache-outbound.md create mode 100644 vault/30-knowledge/concepts/devops-ci-supply-chain-dx.md create mode 100644 vault/30-knowledge/concepts/distributed-tracing-baggage.md create mode 100644 vault/30-knowledge/concepts/fail-open-fail-closed.md create mode 100644 vault/30-knowledge/concepts/idempotency-key-design.md create mode 100644 vault/30-knowledge/concepts/idempotency.md create mode 100644 vault/30-knowledge/concepts/multi-tenancy-isolation-patterns.md create mode 100644 vault/30-knowledge/concepts/observability-log-metric-trace-runbook.md create mode 100644 vault/30-knowledge/concepts/outbox-pattern.md create mode 100644 vault/30-knowledge/concepts/privacy-file-domain-modeling.md create mode 100644 vault/30-knowledge/concepts/resource-identifier-format.md create mode 100644 vault/30-knowledge/concepts/runtime-container-health-migration.md create mode 100644 vault/30-knowledge/concepts/sample-fixture-and-adoption.md create mode 100644 vault/30-knowledge/concepts/security-baseline-jwt-actuator-secrets.md create mode 100644 vault/30-knowledge/concepts/skeleton-governance-registry-verification-test-scorecard.md create mode 100644 vault/30-knowledge/concepts/spring-smart-lifecycle.md create mode 100644 vault/30-knowledge/concepts/streaming-response-patterns.md create mode 100644 vault/30-knowledge/concepts/transaction-boundary-abstraction.md create mode 100644 vault/30-knowledge/concepts/transactional-outbox-pattern.md create mode 100644 vault/30-knowledge/explainer/adapter-identifier.md create mode 100644 vault/30-knowledge/explainer/adapter-outbound.md create mode 100644 vault/30-knowledge/explainer/adapter-persistence.md create mode 100644 vault/30-knowledge/explainer/adapter-web.md create mode 100644 vault/30-knowledge/explainer/application-core.md create mode 100644 vault/30-knowledge/explainer/domain-core.md create mode 100644 vault/30-knowledge/explainer/images/outbound-adapter-architecture.png create mode 100644 vault/30-knowledge/explainer/images/outbound-http-sequence.png create mode 100644 vault/30-knowledge/explainer/shared-contract.md create mode 100644 vault/30-knowledge/explainer/transaction-boundary-abstraction.md create mode 100644 vault/30-knowledge/invest-concepts/field-auto.md create mode 100644 vault/30-knowledge/invest-concepts/field-bigtech-ai.md create mode 100644 vault/30-knowledge/invest-concepts/field-bio-pharma.md create mode 100644 vault/30-knowledge/invest-concepts/field-bitcoin.md create mode 100644 vault/30-knowledge/invest-concepts/field-chem-refining.md create mode 100644 vault/30-knowledge/invest-concepts/field-cosmetics-consumer.md create mode 100644 vault/30-knowledge/invest-concepts/field-defense.md create mode 100644 vault/30-knowledge/invest-concepts/field-dollar.md create mode 100644 vault/30-knowledge/invest-concepts/field-em-china.md create mode 100644 vault/30-knowledge/invest-concepts/field-entertainment.md create mode 100644 vault/30-knowledge/invest-concepts/field-financials.md create mode 100644 vault/30-knowledge/invest-concepts/field-game.md create mode 100644 vault/30-knowledge/invest-concepts/field-gold.md create mode 100644 vault/30-knowledge/invest-concepts/field-internet-platform.md create mode 100644 vault/30-knowledge/invest-concepts/field-krw-rates.md create mode 100644 vault/30-knowledge/invest-concepts/field-map.md create mode 100644 vault/30-knowledge/invest-concepts/field-nuclear-power.md create mode 100644 vault/30-knowledge/invest-concepts/field-oil.md create mode 100644 vault/30-knowledge/invest-concepts/field-robotics.md create mode 100644 vault/30-knowledge/invest-concepts/field-rotation.md create mode 100644 vault/30-knowledge/invest-concepts/field-secondary-battery.md create mode 100644 vault/30-knowledge/invest-concepts/field-semiconductors.md create mode 100644 vault/30-knowledge/invest-concepts/field-shipbuilding.md create mode 100644 vault/30-knowledge/invest-concepts/field-steel-materials.md create mode 100644 vault/30-knowledge/invest-concepts/field-telecom-utility.md create mode 100644 vault/30-knowledge/invest-concepts/field-us-equity.md create mode 100644 vault/30-knowledge/invest-concepts/field-us-rates.md create mode 100644 vault/30-knowledge/invest-plan/active-plan.md create mode 100644 vault/30-knowledge/invest-strategy/strategy.md create mode 100644 vault/30-knowledge/invest/invest-hub.md create mode 100644 vault/30-knowledge/projects/ca-tmpl.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/api-error-envelope-design.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/api-evolution-and-schema.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/boundary-validation-mapping.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/clean-architecture-package-layout.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/config-and-adapter-templates.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/data-layer-persistence-cache-outbound.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/devops-ci-supply-chain-dx.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/idempotency-key-design.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/knowledge-capture-workflow.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/multi-tenancy-isolation-patterns.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/observability-log-metric-trace-runbook.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/privacy-file-domain-modeling.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/resource-identifier-format.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/runtime-container-health-migration.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/sample-fixture-and-adoption.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/security-baseline-jwt-actuator-secrets.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/streaming-response-support.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/transaction-boundary-abstraction.md create mode 100644 vault/30-knowledge/projects/ca-tmpl/transactional-outbox-pattern.md create mode 100644 vault/40-publish/.gitkeep create mode 100644 vault/40-publish/blog-topics/api-deprecation-sunset-header-migration-window-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/archunit-generic-return-type-purity-query-port-2026-06-05.md create mode 100644 vault/40-publish/blog-topics/archunit-jackson-default-typing-cve-2019-14379-block-2026-05-29.md create mode 100644 vault/40-publish/blog-topics/archunit-testcompileonly-fixture-annotation-pattern-2026-06-02.md create mode 100644 vault/40-publish/blog-topics/archunit-violations-as-data-pattern-2026-05-28.md create mode 100644 vault/40-publish/blog-topics/binary-readiness-scorecard-clean-architecture-skeleton-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/boundary-validation-mapper-responsibility-map-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/cache-backend-router-fail-open-decorator-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/cache-consistency-after-commit-stampede-contract-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/ci-gate-wiring-vs-policy-ownership-2026-06-20.md create mode 100644 vault/40-publish/blog-topics/clean-architecture-boundary-enforcement-2026-05-28.md create mode 100644 vault/40-publish/blog-topics/clean-architecture-module-blueprint-2026-05-28.md create mode 100644 vault/40-publish/blog-topics/clean-architecture-reference-project-adoption-2026-06-17.md create mode 100644 vault/40-publish/blog-topics/contract-registry-schema-owner-vs-row-owner-gate-2026-06-20.md create mode 100644 vault/40-publish/blog-topics/contract-verification-suite-release-gates-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/digest-first-java-release-pipeline-2026-06-21.md create mode 100644 vault/40-publish/blog-topics/distributed-lock-transaction-commit-boundary-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/domain-modeling-guardrails-as-archunit-fitness-functions-2026-06-05.md create mode 100644 vault/40-publish/blog-topics/env-example-drift-gate-gradle-2026-06-06.md create mode 100644 vault/40-publish/blog-topics/executable-clean-architecture-onboarding-2026-06-25.md create mode 100644 vault/40-publish/blog-topics/five-stage-local-bootstrap-contract-2026-06-24.md create mode 100644 vault/40-publish/blog-topics/framework-free-method-authorization-clean-architecture-2026-06-08.md create mode 100644 vault/40-publish/blog-topics/gitea-act-dependency-security-gate-portability-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/gradle9-java21-static-analysis-baseline-2026-06-20.md create mode 100644 vault/40-publish/blog-topics/hikaricp-inter-knob-constraints-startup-guard-2026-06-09.md create mode 100644 vault/40-publish/blog-topics/idempotency-executor-application-layer-clean-architecture-2026-06-09.md create mode 100644 vault/40-publish/blog-topics/identifier-governance-rule-scoping-by-id-kind-2026-06-01.md create mode 100644 vault/40-publish/blog-topics/java21-context-propagation-strategy-virtual-threads-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/jdk-httpclient-dns-connectexception-classification-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/jvm-oom-vs-container-oomkill-exit-137-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/logback-layer1-secret-masking-json-vs-pattern-2026-06-14.md create mode 100644 vault/40-publish/blog-topics/manifest-driven-agent-harness-policy-engine.md create mode 100644 vault/40-publish/blog-topics/micrometer-meterfilter-resilience4j-functioncounter-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/nplus1-lab-checkoutable-api-replay-2026-07-15.md create mode 100644 vault/40-publish/blog-topics/operational-error-envelope-meta-category-migration-2026-06-01.md create mode 100644 vault/40-publish/blog-topics/persistence-audit-metadata-clean-architecture-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/post-implementation-knowledge-capture-workflow-2026-05-28.md create mode 100644 vault/40-publish/blog-topics/repository-capability-archunit-fitness-function-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/runbook-coverage-junit-contract-test-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/sample-domain-contract-fixture-clean-architecture-2026-06-10.md create mode 100644 vault/40-publish/blog-topics/sample-fixture-dual-mode-build-matrix-2026-06-25.md create mode 100644 vault/40-publish/blog-topics/secret-source-port-restart-only-rotation-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/skip-locked-outbox-per-aggregate-fifo-gate-2026-06-11.md create mode 100644 vault/40-publish/blog-topics/spring-actuator-health-probe-group-split-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/spring-async-taskdecorator-bounded-executor-saturation-shutdown-2026-06-13.md create mode 100644 vault/40-publish/blog-topics/spring-boot-3-configprops-record-multi-constructor-binding-2026-06-12.md create mode 100644 vault/40-publish/blog-topics/spring-boot-serialization-contract-pins-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/spring-boot-startup-exit-code-propagation-2026-06-10.md create mode 100644 vault/40-publish/blog-topics/spring-conditional-on-property-optional-adapter-template-2026-06-09.md create mode 100644 vault/40-publish/blog-topics/spring-responseentityexceptionhandler-transport-failure-envelope-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/spring-security-filter-layer-error-envelope-2026-06-08.md create mode 100644 vault/40-publish/blog-topics/streaming-response-not-supported-archunit-ban-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/test-taxonomy-archunit-enforcement-2026-06-19.md create mode 100644 vault/40-publish/blog-topics/transaction-isolation-vendor-default-pin-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/transaction-port-abstraction-over-spring-transactional-2026-05-28.md create mode 100644 vault/40-publish/blog-topics/trivy-suppression-governance-static-gate-2026-06-20.md create mode 100644 vault/40-publish/blog-topics/ulid-crockford-base32-excluded-letters-2026-06-01.md create mode 100644 vault/40-publish/blog-topics/w3c-traceparent-fork-activated-seam-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/webhook-full-jitter-dlq-observability-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/webhook-signature-replay-contract-2026-07-02.md create mode 100644 vault/40-publish/blog-topics/webhook-ssrf-egress-proxy-redirect-block-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-api-error-envelope-design-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-api-evolution-and-schema-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-boundary-validation-mapping-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-clean-architecture-package-layout-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-config-and-adapter-templates-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-data-layer-persistence-cache-outbound-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-devops-ci-supply-chain-dx-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-idempotency-key-design-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-knowledge-capture-workflow-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-multi-tenancy-isolation-patterns-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-observability-log-metric-trace-runbook-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-privacy-file-domain-modeling-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-resource-identifier-format-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-runtime-container-health-migration-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-sample-fixture-and-adoption-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-security-baseline-jwt-actuator-secrets-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-skeleton-governance-registry-verification-test-scorecard-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-streaming-response-support-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-transaction-boundary-abstraction-2026-07-02.md create mode 100644 vault/40-publish/blog/ca-tmpl-transactional-outbox-pattern-2026-07-02.md create mode 100644 vault/40-publish/interviews/archunit-manual-importer-vs-analyzeclasses.md create mode 100644 vault/40-publish/interviews/archunit-static-analysis-limits.md create mode 100644 vault/40-publish/interviews/archunit-violations-as-data-pattern-2026-06-02.md create mode 100644 vault/40-publish/interviews/async-executor-saturation-context-propagation-2026-06-13.md create mode 100644 vault/40-publish/interviews/ci-release-gate-fan-in-blocking-2026-06-20.md create mode 100644 vault/40-publish/interviews/clean-architecture-boundary-enforcement.md create mode 100644 vault/40-publish/interviews/clean-architecture-domain-onboarding-guardrails.md create mode 100644 vault/40-publish/interviews/clean-architecture-identifier-generation.md create mode 100644 vault/40-publish/interviews/clean-architecture-method-authorization-without-spring-coupling-2026-06-08.md create mode 100644 vault/40-publish/interviews/clean-architecture-module-blueprint.md create mode 100644 vault/40-publish/interviews/crown-one-query-vs-cqrs-lite-read-model.md create mode 100644 vault/40-publish/interviews/deterministic-logback-asyncappender-drop-metric-test-2026-06-14.md create mode 100644 vault/40-publish/interviews/digest-first-supply-chain-release-gates.md create mode 100644 vault/40-publish/interviews/domain-modeling-guardrails-archunit-2026-06-05.md create mode 100644 vault/40-publish/interviews/formatter-vs-style-linter-responsibility-split-2026-06-20.md create mode 100644 vault/40-publish/interviews/gradle-sample-off-test-classpath-isolation.md create mode 100644 vault/40-publish/interviews/idempotency-rate-limit-design-tradeoffs-2026-06-09.md create mode 100644 vault/40-publish/interviews/jwt-resource-server-fine-grained-error-classification-2026-06-08.md create mode 100644 vault/40-publish/interviews/manifest-driven-multi-platform-agent-harness.md create mode 100644 vault/40-publish/interviews/native-query-addscalar-runtime-validation.md create mode 100644 vault/40-publish/interviews/operational-error-envelope-and-observability-foundation.md create mode 100644 vault/40-publish/interviews/optional-adapter-3-layer-disabled-detection-2026-06-09.md create mode 100644 vault/40-publish/interviews/post-implementation-knowledge-capture.md create mode 100644 vault/40-publish/interviews/sample-domain-contract-fixture-clean-architecture.md create mode 100644 vault/40-publish/interviews/shared-contract-and-sample-isolation.md create mode 100644 vault/40-publish/interviews/single-command-local-bootstrap.md create mode 100644 vault/40-publish/interviews/spring-jpa-flyway-initialization-lifecycle-circular-dependency.md create mode 100644 vault/40-publish/interviews/startup-fail-fast-config-validation-2026-06-06.md create mode 100644 vault/40-publish/interviews/transaction-port-vs-spring-transactional.md create mode 100644 vault/40-publish/interviews/transactional-outbox-skip-locked-implementation-2026-06-11.md create mode 100644 vault/40-publish/interviews/trivy-suppression-dual-control-governance-2026-06-20.md create mode 100644 vault/40-publish/publish-blog/api-error-envelope-blog.md create mode 100644 vault/40-publish/publish-blog/api-evolution-schema-blog.md create mode 100644 vault/40-publish/publish-blog/boundary-validation-mapping-blog.md create mode 100644 vault/40-publish/publish-blog/ci-supply-chain-blog.md create mode 100644 vault/40-publish/publish-blog/clean-architecture-package-layout-blog.md create mode 100644 vault/40-publish/publish-blog/data-layer-persistence-cache-outbound-blog.md create mode 100644 vault/40-publish/publish-blog/optional-adapter-config-contract-blog.md create mode 100644 vault/40-publish/topics-interview/clean-architecture.md create mode 100644 vault/50-journal/.gitkeep create mode 100644 vault/50-journal/daily-notes/2026-05-27.md create mode 100644 vault/50-journal/daily-notes/2026-05-28.md create mode 100644 vault/50-journal/daily-notes/2026-06-14.md create mode 100644 vault/50-journal/daily-notes/2026-06-30.md create mode 100644 vault/50-journal/daily-tasks/README.md create mode 100644 vault/50-journal/daily-tasks/develop/2026-05-29-archunit-controller-domain-return-rule.md create mode 100644 vault/50-journal/daily-tasks/infra/2026-05-29-actuator-readiness-probe-db-disconnect-detection.md create mode 100644 vault/50-journal/invest-daily/2026-06-06.md create mode 100644 vault/50-journal/invest-daily/2026-06-08.md create mode 100644 vault/50-journal/invest-ledger/ledger.md create mode 100644 vault/90-archive/.gitkeep create mode 100644 vault/90-archive/archive/branch-notes/feature-template-instantiation-contract.md create mode 100644 vault/README.md create mode 120000 wiki/blog/ca-tmpl-api-error-envelope-design-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-api-evolution-and-schema-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-boundary-validation-mapping-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-clean-architecture-package-layout-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-config-and-adapter-templates-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-data-layer-persistence-cache-outbound-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-devops-ci-supply-chain-dx-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-idempotency-key-design-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-knowledge-capture-workflow-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-multi-tenancy-isolation-patterns-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-observability-log-metric-trace-runbook-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-privacy-file-domain-modeling-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-resource-identifier-format-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-runtime-container-health-migration-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-sample-fixture-and-adoption-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-security-baseline-jwt-actuator-secrets-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-skeleton-governance-registry-verification-test-scorecard-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-streaming-response-support-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-transaction-boundary-abstraction-2026-07-02.md create mode 120000 wiki/blog/ca-tmpl-transactional-outbox-pattern-2026-07-02.md create mode 120000 wiki/concepts/api-error-envelope-design.md create mode 120000 wiki/concepts/api-evolution-and-schema.md create mode 120000 wiki/concepts/archunit-scope-classpath-vs-package-filter.md create mode 120000 wiki/concepts/boundary-validation-and-dto-mapping.md create mode 120000 wiki/concepts/circuit-breaker.md create mode 120000 wiki/concepts/clean-architecture-package-layout.md create mode 120000 wiki/concepts/config-and-adapter-templates.md create mode 120000 wiki/concepts/data-layer-persistence-cache-outbound.md create mode 120000 wiki/concepts/devops-ci-supply-chain-dx.md create mode 120000 wiki/concepts/distributed-tracing-baggage.md create mode 120000 wiki/concepts/fail-open-fail-closed.md create mode 120000 wiki/concepts/idempotency-key-design.md create mode 120000 wiki/concepts/idempotency.md create mode 120000 wiki/concepts/multi-tenancy-isolation-patterns.md create mode 120000 wiki/concepts/observability-log-metric-trace-runbook.md create mode 120000 wiki/concepts/outbox-pattern.md create mode 120000 wiki/concepts/privacy-file-domain-modeling.md create mode 120000 wiki/concepts/resource-identifier-format.md create mode 120000 wiki/concepts/runtime-container-health-migration.md create mode 120000 wiki/concepts/sample-fixture-and-adoption.md create mode 120000 wiki/concepts/security-baseline-jwt-actuator-secrets.md create mode 120000 wiki/concepts/skeleton-governance-registry-verification-test-scorecard.md create mode 120000 wiki/concepts/spring-smart-lifecycle.md create mode 120000 wiki/concepts/streaming-response-patterns.md create mode 120000 wiki/concepts/transaction-boundary-abstraction.md create mode 120000 wiki/concepts/transactional-outbox-pattern.md create mode 120000 wiki/explainer/adapter-identifier.md create mode 120000 wiki/explainer/adapter-outbound.md create mode 120000 wiki/explainer/adapter-persistence.md create mode 120000 wiki/explainer/adapter-web.md create mode 120000 wiki/explainer/application-core.md create mode 120000 wiki/explainer/domain-core.md create mode 120000 wiki/explainer/images/outbound-adapter-architecture.png create mode 120000 wiki/explainer/images/outbound-http-sequence.png create mode 120000 wiki/explainer/shared-contract.md create mode 120000 wiki/explainer/transaction-boundary-abstraction.md create mode 120000 wiki/invest-concepts/field-auto.md create mode 120000 wiki/invest-concepts/field-bigtech-ai.md create mode 120000 wiki/invest-concepts/field-bio-pharma.md create mode 120000 wiki/invest-concepts/field-bitcoin.md create mode 120000 wiki/invest-concepts/field-chem-refining.md create mode 120000 wiki/invest-concepts/field-cosmetics-consumer.md create mode 120000 wiki/invest-concepts/field-defense.md create mode 120000 wiki/invest-concepts/field-dollar.md create mode 120000 wiki/invest-concepts/field-em-china.md create mode 120000 wiki/invest-concepts/field-entertainment.md create mode 120000 wiki/invest-concepts/field-financials.md create mode 120000 wiki/invest-concepts/field-game.md create mode 120000 wiki/invest-concepts/field-gold.md create mode 120000 wiki/invest-concepts/field-internet-platform.md create mode 120000 wiki/invest-concepts/field-krw-rates.md create mode 120000 wiki/invest-concepts/field-map.md create mode 120000 wiki/invest-concepts/field-nuclear-power.md create mode 120000 wiki/invest-concepts/field-oil.md create mode 120000 wiki/invest-concepts/field-robotics.md create mode 120000 wiki/invest-concepts/field-rotation.md create mode 120000 wiki/invest-concepts/field-secondary-battery.md create mode 120000 wiki/invest-concepts/field-semiconductors.md create mode 120000 wiki/invest-concepts/field-shipbuilding.md create mode 120000 wiki/invest-concepts/field-steel-materials.md create mode 120000 wiki/invest-concepts/field-telecom-utility.md create mode 120000 wiki/invest-concepts/field-us-equity.md create mode 120000 wiki/invest-concepts/field-us-rates.md create mode 100644 wiki/invest-plan/.gitkeep create mode 120000 wiki/invest-plan/active-plan.md create mode 100644 wiki/invest-strategy/.gitkeep create mode 120000 wiki/invest-strategy/strategy.md create mode 100644 wiki/invest/.gitkeep create mode 120000 wiki/invest/invest-hub.md create mode 100644 wiki/invest/invest-hub/.gitkeep create mode 100644 wiki/llm-wiki.md create mode 100644 wiki/log.md create mode 120000 wiki/projects/ca-tmpl.md create mode 120000 wiki/projects/ca-tmpl/api-error-envelope-design.md create mode 120000 wiki/projects/ca-tmpl/api-evolution-and-schema.md create mode 120000 wiki/projects/ca-tmpl/boundary-validation-mapping.md create mode 120000 wiki/projects/ca-tmpl/clean-architecture-package-layout.md create mode 120000 wiki/projects/ca-tmpl/config-and-adapter-templates.md create mode 120000 wiki/projects/ca-tmpl/data-layer-persistence-cache-outbound.md create mode 120000 wiki/projects/ca-tmpl/devops-ci-supply-chain-dx.md create mode 120000 wiki/projects/ca-tmpl/idempotency-key-design.md create mode 120000 wiki/projects/ca-tmpl/knowledge-capture-workflow.md create mode 120000 wiki/projects/ca-tmpl/multi-tenancy-isolation-patterns.md create mode 120000 wiki/projects/ca-tmpl/observability-log-metric-trace-runbook.md create mode 120000 wiki/projects/ca-tmpl/privacy-file-domain-modeling.md create mode 120000 wiki/projects/ca-tmpl/resource-identifier-format.md create mode 120000 wiki/projects/ca-tmpl/runtime-container-health-migration.md create mode 120000 wiki/projects/ca-tmpl/sample-fixture-and-adoption.md create mode 120000 wiki/projects/ca-tmpl/security-baseline-jwt-actuator-secrets.md create mode 120000 wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard.md create mode 120000 wiki/projects/ca-tmpl/streaming-response-support.md create mode 120000 wiki/projects/ca-tmpl/transaction-boundary-abstraction.md create mode 120000 wiki/projects/ca-tmpl/transactional-outbox-pattern.md create mode 120000 wiki/publish-blog/api-error-envelope-blog.md create mode 120000 wiki/publish-blog/api-evolution-schema-blog.md create mode 120000 wiki/publish-blog/boundary-validation-mapping-blog.md create mode 120000 wiki/publish-blog/ci-supply-chain-blog.md create mode 120000 wiki/publish-blog/clean-architecture-package-layout-blog.md create mode 120000 wiki/publish-blog/data-layer-persistence-cache-outbound-blog.md create mode 120000 wiki/publish-blog/optional-adapter-config-contract-blog.md create mode 120000 wiki/topics-interview/clean-architecture.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..9d77807 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,137 @@ +# LLM Wiki — Agent Operating Rules + +본 파일은 **Antigravity CLI / Codex CLI / 기타 universal agent CLI** 가 세션 시작 시 자동 로드하는 entry point 다. Claude Code 는 별도로 [`CLAUDE.md`](CLAUDE.md) 를 자동 로드한다 (본 파일과 동일 정책의 풀버전). + +> **이 저장소는 무엇인가:** 원본 자료 (`raw/`) 를 **검증된 실무 기술 문서** (`wiki/concepts/` · `wiki/projects/`) 로 변환하고, 그로부터 외부 산출물 (interview / portfolio / blog) 을 파생하는 **파이프라인**. 주된 도메인: 백엔드 / 인프라. + +## 최상위 원칙 + +``` +raw 자료는 증거다. +wiki/concepts 와 wiki/projects 는 검증된 실무 기술 문서 (canonical) 이다. +interview / portfolio / blog 는 canonical 에서만 파생된 산출물이다. +``` + +파생 산출물 (`wiki/interview/`, `wiki/portfolio/`, `wiki/blog/`) 은 **반드시** canonical 경유. raw 또는 daily/branch 에서 직접 파생 금지. + +## 디렉터리 layout + +| 위치 | 역할 | +|---|---| +| `raw/` | 가공 전 원본 자료 (영구 보관: `branch-notes/`, `daily-notes/`) | +| `wiki/` | 정리된 재사용 가능 지식 (`concepts/` · `projects/` · `interview/` · `portfolio/` · `blog/`) | +| `templates/` | 카테고리별 출력 형식 정의 (27개, `templates/blog-topic-template.md` 포함) | +| `rules/` | **3개 모델 공유 SSOT** — 14개 rule (Claude / Antigravity / Codex 동일 본문) | +| `.agents/plugins/wiki-superpowers/` | Antigravity plugin — skills / agents / rules-split | +| `.codex/agents/` | Codex CLI agent manual-invoke definitions | +| `.claude/` | Claude Code skill + slash commands | +| `docs/superpowers/specs/` | multi-doc 보고서 저장 위치 | + +## 핵심 rules (lazy-load, 필요 시점 정독) + +| Rule | 필독 시점 | 위치 | +|---|---|---| +| Upward link + slug + frontmatter + tag + Cluster + Derived 게이트 | 새 raw / wiki 문서 작성 시 | [`rules/linking-rules.md`](rules/linking-rules.md) | +| 파일·디렉토리·branch prefix 명명 규칙 | 새 파일 slug 결정 시 | [`rules/naming-conventions.md`](rules/naming-conventions.md) | +| `tags:` 5계층 허용 어휘 | frontmatter `tags` 채울 때 | [`rules/tag-taxonomy.md`](rules/tag-taxonomy.md) | +| Evidence matrix + 명명된 실패 모드 + subagent dispatch | multi-doc research / review / audit 시 | [`rules/evidence-first-research.md`](rules/evidence-first-research.md) | +| 보고서 §0~§8 + Verdict 산식 + §7.1 self-grep | 보고서 작성 시 | [`rules/reporting-standards.md`](rules/reporting-standards.md) (root SSOT 559줄) | +| Goal/Assumption/Action 사슬 + Counterargument + Self-grep + 금지어 (7 Contracts) | 권고·브레인스토밍·개념 설명·비교·plan 리뷰·direct-answer 시 | [`rules/advisory-depth.md`](rules/advisory-depth.md) (root SSOT 418줄) | +| 컨퍼런스급 다이어그램 표준 v2 (8항 self-check) | draw.io / Mermaid 작성 시 | [`rules/diagram-standards.md`](rules/diagram-standards.md) (root SSOT 379줄) | + +## Plugin entry (Antigravity) + +문서 작업 시작 시 invoke: + +``` +.agents/plugins/wiki-superpowers/skills/wiki-workflow/SKILL.md +``` + +본 skill 이 dispatch decision tree + STOP self-check + Output-Format Hard Gate 를 강제. 10 agents (`wiki-doc-author`, `wiki-source-summarizer`, `wiki-research-lane`, `wiki-link-verifier`, `wiki-adversarial-reviewer`, `wiki-diagram-reviewer`, `wiki-decision-researcher`, `branch-depth-auditor`, `coverage-auditor`, `wiki-consistency-auditor`) 가 정의되어 있음. + +## Frontmatter 표준 + +모든 `wiki/` 문서: + +```yaml +--- +title: <문서 제목> +source_type: official-doc | company-tech-blog | personal-blog | lecture | project-note | error-note | job-posting | blog-topic | interview-prep | daily-note | branch-note | concept | interview | portfolio | blog | llm-generated +status: raw | draft | reviewed | verified | published-ready | stale | needs-confirmation +confidence: high | medium | low | unknown +tags: [, , ...] +related_projects: [] +last_reviewed: YYYY-MM-DD +--- +``` + +`raw/` 는 최소한 `title`, `source_type`, `url`(있다면), `tags` 만 있어도 됨. + +## Source 신뢰도 + +| source_type | 취급 | +|---|---| +| `official-doc` | 기준 / 정의로 사용 가능 | +| `company-tech-blog` | 사례·관점. **공식 best practice 로 취급 금지** | +| `personal-blog` | 참고 자료 | +| `lecture` | 학습 자료 | +| `blog-topic` | 채용공고가 아닌 작업·학습·트러블슈팅 기반 블로그 글감 원석 | +| `llm-generated` | 검토 전 초안. **high confidence 금지** | + +## Project 증거 등급 (외부 공개 가능 여부) + +- `actually-implemented` — 코드 존재 ✓ +- `locally-verified` — 로컬·dev 환경 확인 ✓ +- `prod-verified` — 운영 환경 검증 (로그·측정·인시던트) ✓ +- `documented-only` — 문서에만 ❌ 외부 공개 금지 +- `planned` — 계획만 ❌ 외부 공개 금지 +- `needs-confirmation` — 확인 필요 ❌ 외부 공개 금지 + +`wiki/interview/` · `wiki/portfolio/` · `wiki/blog/` 작성 시 위 ✓ 등급만 허용. + +## 절대 금지 + +- 출처 없는 단정적 진술 +- 공식 문서와 기술블로그 혼동 +- `documented-only` / `planned` 를 `actually-implemented` 처럼 표현 +- LLM 생성 내용을 검증 없이 `high` confidence 로 분류 +- **파생 산출물 (`wiki/interview/`, `wiki/portfolio/`, `wiki/blog/`) 을 canonical 경유 없이 생성** +- **원천 canonical status 가 `reviewed | verified | published-ready` 미만인 상태에서 파생 생성** +- **`/ingest` 로 `wiki/interview/` · `wiki/portfolio/` · `wiki/blog/` 에 문서 작성** +- **branch-note slug 에 numbered hierarchy 사용** (`feature-X-1` 등). slug 는 **구현 내용** 4~8 단어 영문 kebab-case. 계층은 frontmatter `parent_branch:` + `## Parent` 섹션으로만. +- **`develop-` prefix 사용** — 제거됨. 기능 구현 작업은 규모 무관 `feature-`. +- 금지 마케팅 단어 (`100%`, `완벽`, `극한`, `절대로`, `최강`, `역사상 가장`, `명품`) 를 verbatim quote 밖에서 사용 + +## 파이프라인 게이트 (CLAUDE.md §15 핵심) + +| 명령 | 입력 | 출력 | 게이트 | +|---|---|---|---| +| `/ingest` | `raw/*` | `wiki/concepts/` · `wiki/projects/` **만** | — | +| `/projectize` | `wiki/concepts/` | `wiki/projects/` **만** | 원천 status ≥ `reviewed` 권장 | +| `/interviewize` | `wiki/concepts/` · `wiki/projects/` | `wiki/interview/` | 원천 status ∈ {reviewed, verified, published-ready} — 미달 시 중단 | +| `/blogify` | `wiki/concepts/` · `wiki/projects/` | `wiki/blog/` | 동상 | +| (수동) | `wiki/projects/` | `wiki/portfolio/` | 본문 등급은 §"Project 증거 등급" 준수 | + +## Runtime hook enforcement (Antigravity 한정) + +`~/.gemini/antigravity-cli/hooks/wiki_hard_gate.py` (PreToolUse) 가 `docs/superpowers/specs/*.md` write 시 G1~G4 자동 검사: + +- G1: §7.1 의 `$ sed -n` / `$ grep -nF` 명령 존재 +- G2: 금지 마케팅 단어 7개 (verbatim quote 밖) +- G3: `Verdict: COMPLETE` + §3-1 산식 (`M==N AND P==R`) 표기 +- G4: ≥5 findings master 에 §4-1 Adversarial Review 존재 + +**Hook 통과 ≠ 합격.** chat 본문 응답, 증거 진실성 (실제 sed/grep 실행), subagent dispatch 판단, 다른 경로 write 등은 모두 agent self-check 단독 책임. 자세히: [`~/.gemini/antigravity-cli/hooks/README.md`](file:///home/donghyeon/.gemini/antigravity-cli/hooks/README.md). + +## 작업 우선순위 + 출력 언어 + +1. 사실 정확성 > 표현 매끄러움 +2. 출처 명시 > 빠른 작성 +3. 과장 방지 > 강한 어조 +4. 재사용 가능성 > 단발성 완성도 + +본문 산문은 **한국어** 기본. 코드 / CLI 명령 / 공식 용어 (`connection pool`, `idempotent` 등) 는 원문 유지. + +## 전체 CLAUDE.md 본문이 필요할 때 + +본 AGENTS.md 는 CLAUDE.md 의 ≤150줄 요약. 상세 (§4 metadata, §6 등급, §11 절대 금지 전체, §15 파이프라인, §16 품질 10항목 등) 가 필요하면 [`CLAUDE.md`](CLAUDE.md) 직접 정독. CLAUDE.md 는 모든 모델 공통 SSOT. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..960b0c2 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,409 @@ +# LLM Wiki — Claude Code 운영 규칙 + +이 파일은 **운영 규칙**만 담습니다. 개념 설명, 공식 문서 요약, 프로젝트 본문, 면접 답변, 블로그 초안은 절대 여기에 두지 않습니다. + +--- + +## 1. 이 저장소의 목적 + +원본 자료(`raw/`)를 **검증된 실무 기술 문서**로 변환하고, 그로부터 외부 산출물을 파생하는 **파이프라인**입니다. + +### 최상위 원칙 + +```text +raw 자료는 증거다. +wiki/concepts와 wiki/projects는 검증된 실무 기술 문서(canonical)이다. +interview / portfolio / blog는 canonical에서 파생된 산출물이다. +``` + +자세한 위계와 파생 규칙은 §15. + +### 메타 정보 + +- 주된 도메인: 백엔드 / 인프라 +- 그 외 주제도 허용. 단, 모든 문서는 동일한 규칙을 따라야 함. +- 최종 사용처: 면접, 이력서, 포트폴리오, README, 블로그. + +### 핵심 흐름 + +```text +캡처: /daily | /branch → raw/ +변환: raw/ → /ingest → wiki/concepts + wiki/projects (canonical) +품질: wiki/* → /tag · /lint · /sync · /query (+ 브랜치 게이트: /depth · /coverage) +파생: wiki/concepts + wiki/projects → /interviewize · /blogify · /explain · (wiki/portfolio 수동) +``` + +파생 산출물(`wiki/interview/`, `wiki/portfolio/`, `wiki/blog/`)은 **반드시** canonical 경유. raw 또는 daily/branch에서 직접 가지 못함. + +--- + +## 2. 디렉터리 역할 + +| 위치 | 역할 | +|------|------| +| `CLAUDE.md` | 이 파일. 운영 규칙만. | +| `raw/` | 가공 전 원본 자료. 출처 보존. | +| `wiki/` | 정리된 재사용 가능 지식. | +| `templates/` | 출력 형식 정의. | +| `.claude/commands/` | 반복 작업 자동화 — **캡처**: `/daily`, `/branch`, `/branch-spec`, `/project`, `/project-spec` · **변환/품질**: `/ingest`, `/tag`, `/lint`, `/sync`, `/query`, `/depth`, `/coverage`, `/migrate-claims` · **출력**: `/projectize`, `/interviewize`, `/blogify`, `/explain`. | + +### 주요 문서 wikilinks + +운영 규칙(본 파일)과 함께 사용되는 핵심 문서들. Obsidian Graph에서 이 hub와 연결되어야 함: + +- **Hub / 로그**: [[wiki/llm-wiki]] (vault MOC), [[wiki/log]] +- **메타 규약 / Rules (필수 정독, top-level `rules/` — Claude / Antigravity / codex-cli 공유 SSOT)**: + - [[rules/linking-rules]] — Mandatory upward link 표 + 다중 부모 + 양방향 작성 패턴 + Hub/MOC 명명 컨벤션 (named hub, `index.md` 금지) + 검증 체크리스트. 모든 raw/wiki 문서가 따르는 single source of truth. + - [[rules/naming-conventions]] — 파일·디렉토리·branch prefix·다이어그램 명명 규칙. + - [[rules/tag-taxonomy]] — `tags:` 5계층 허용 어휘 + 동의어 정책. + - [[rules/diagram-standards]] — **컨퍼런스급 다이어그램 표준 v2 (minimalist-first)** — Toss SLASH / Kakao if(dev) / Naver DEVIEW 수준. draw.io 아키텍처 + Mermaid sequence/ER 작성 시 정독. element budget (Vertex ≤ 10 / Edge ≤ 8 / Callout ≤ 1) + 8항 self-check (§14) 모두 만족 필수. `wiki-diagram-reviewer` 가 ≥95/100 점 채점. + - [[rules/evidence-first-research]] — multi-doc 정독 시 verbatim quote + 명명된 실패 모드. + - [[rules/reporting-standards]] — multi-doc 보고서 §0~§8 템플릿 + Output Split + Verdict 산식. + - [[rules/advisory-depth]] — 7 Contracts (Goal/Assumption/Action chain · Exhaustive Options · Plan Gap · Direct-Response · Citation Discipline · Self-Grep · Forbidden Words). + - [[rules/prose-style]] — 파생 산출물(interview/blog/portfolio) 한국어 윤문 + "쉬운 설명" 기준. 존댓말 · 적당히 긴 길이 · 개발 용어만 영어 · 전문 용어 한 줄 풀이 · 쉬운 요약 먼저 + 명명된 실패 모드. `/interviewize`·`/blogify` 가 참조. + - [[rules/branch-depth-gate]] — 브랜치 노트가 *코딩 착수해도 되묻지 않을 만큼* 깊은지 판정하는 4축·깊이 사다리(L0~L3)·명명된 실패 모드. `/depth` 명령(`.claude/commands/depth.md`)과 `branch-depth-auditor` agent + 결정론 린터 `.claude/hooks/wiki_structure_lint.py`가 함께 집행. + - [[rules/consistency-contract]] — 문서 간 일관성 계약: Single-Owner(결정·관심사당 owner 문서 정확히 1개) + Reference-Only(타 문서는 `[[owner]] D` 포인터 + 1줄 요약만, 재진술 금지) + owner 변경 시 역참조 비차단 전파 알림. `/sync` 명령 + `wiki-consistency-auditor` agent + 결정론 검사기 `.claude/hooks/wiki_consistency_check.py` 가 집행. + - [[rules/extraction-tiering]] — Tiered Extraction 계약: 4-Tier(T0 결정론 / T1 외부 구독 codex·agy / T2 haiku / T3 sonnet / T4 opus) + 5계명(외부 CLI = read-only 추출기 · 무검증 발췌 소비 금지 · engine funnel 필수 · opus 에 raw corpus 반입 금지 · fallback 사다리 기록). `extraction-broker` agent + `scripts/deep-research/deep_research/extract.py`(quote-verifier 내장)·`vote.py`(cross-vendor quorum 표) + `wiki_consistency_check.py --packets` 가 집행. + - [[rules/subagent-input-contracts]] — controller가 dispatch *전에* 모을 입력을 agent/명령별 form schema로 고정(3-rule: Pre-fill · Missing→행동 명시 · No SSOT 이중화) + 명명된 실패 모드. `/branch-spec`(`.claude/commands/branch-spec.md`)이 이 계약을 소비해 빈 브랜치 노트를 *되묻지 않을 수준*으로 채움(근거 없으면 자동조사 → 실패 시 `UNSUPPORTED_DECISION` 라벨 → 끝에 `/depth` + `/coverage` 자동 게이트, 루프 천장 2회). +- **Claude Code 자동화** (`.claude/`) — narrative 스타일, `tools:`/`model:` frontmatter: + - `.claude/skills/wiki-workflow/SKILL.md` — 문서 작업 진입점. 사용자 의도에 따라 적절한 agent dispatch. + - `.claude/agents/wiki-doc-author.md` — 새 raw 문서 생성 또는 기존 비-template 문서 마이그레이션 (category-aware, mode: create | migrate). + - `.claude/agents/wiki-source-summarizer.md` — URL → raw 자료 (verbatim quote + self-grep). + - `.claude/agents/wiki-link-verifier.md` — orphan / broken wikilink / Cluster 누락 감사 (read-only). + - `.claude/agents/wiki-research-lane.md` — 다수 raw 정독 → 합성 권고 (read-only). + - `.claude/agents/extraction-broker.md` — bulk 발췌 브로커 (haiku, read-only) — 외부 구독 CLI 드라이버(`extract.py`) 구동 + 실패분 자가 재발췌 + 검증된 digest 만 반환 (`rules/extraction-tiering.md` T1+T2). **Claude Code 전용** — 3-플랫폼 포팅 대상 아님 (T2 haiku 브로커는 Claude 모델 계층; Codex/Antigravity 에선 오케스트레이터가 `extract.py` 를 직접 호출). + - `.claude/agents/wiki-adversarial-reviewer.md` — 리서치/감사 draft falsification (KEEP/DOWNGRADE/REJECT 권고, read-only). + - `.claude/agents/wiki-diagram-reviewer.md` — `.drawio` 다이어그램 채점 (≥95/100 PASS, read-only). + - `.claude/agents/wiki-decision-researcher.md` — 기술 결정 alternatives 조사 (read-only; WebSearch + 사용자 승인 → **dispatch 요청 방출**, `wiki-source-summarizer` × N×2 실 dispatch 는 controller 가 수행 → 비교 매트릭스 + 조건부 권고). + - `.claude/agents/project-readiness-auditor.md` — project-note(hub) 완성도 의미 게이트 (read-only, ca-skeleton caliber 판정). **Claude Code 전용** — Codex/Antigravity 포팅 없음(`/project`·`/project-spec` 파이프라인은 3-플랫폼 패리티 예외). **투자 파이프라인(`/invest-*` 6개 명령 + invest 템플릿)도 Claude Code 전용 — Codex/Antigravity 포팅 대상 아님** (개인 투자 관리용, `/project` 파이프라인과 동일한 3-플랫폼 예외). +- **Antigravity CLI 자동화** (`.agents/agents//agent.json`) — `.claude/`와 동일 10개 agent (단 `project-readiness-auditor`·`extraction-broker` 는 Claude 전용 — 3-플랫폼 포팅 대상 아님) (위 7개 + `branch-depth-auditor`·`coverage-auditor`·`wiki-consistency-auditor`) 의 Antigravity 포트. Antigravity CLI native subagent registry 형식 (workspace = `.agents/agents//agent.json`, global = `~/.gemini/antigravity-cli/agents//agent.json`). 각 `agent.json` 의 `config.customAgent.systemPromptSections[0].content` 가 system prompt, `toolNames` 로 도구 권한 제어 (read-only agent 는 `write_to_file`/`replace_file_content`/`multi_replace_file_content` 제외). **G1 Pre-Read Proof, G2 Post-Write Validator, G3 Output Schema with `{{ }}` placeholders, G4 Enumerated STOP Conditions** 4가지 hard gate가 system prompt 본문에 포함됨 (Gemini의 narrative 무시 / 자체 검증 건너뛰기 / NEEDS_CONTEXT 회피 / 출력 스키마 흐트러짐을 차단). 동일 `rules/`와 `templates/` 참조. **System prompt SSOT 는 `.agents/plugins/wiki-superpowers/agents/*.md`**. Antigravity CLI 가 직접 인식하는 것은 `.agents/agents//agent.json` 이므로, SSOT `.md` 를 편집하면 대응 `agent.json` 도 함께 갱신해야 반영됨(안 하면 변경 사항 미반영). ⚠️ **자동 생성기 `scripts/sync_automation.py` 는 현재 repo 에 없음**(2026-06-06 확인; `scripts/` 는 존재하나 `sync_automation.py` 만 부재 — 2026-07-14 재확인) — 복원 전까지 SSOT↔variant 동기화는 **수기**로 하고 3 플랫폼 패리티를 직접 유지한다. +- **Codex CLI 자동화** (`.codex/agents/`) — `.claude/`와 본문은 같은 agent. codex 환경에 맞춰 frontmatter 에서 `tools:`/`model:` 제거 + 본문 tool 표현 일반화. Codex 는 **native subagent 를 `.codex/agents/*.toml` 로 등록**(`developer_instructions` + `sandbox_mode`) — `.agents/plugins/wiki-superpowers/agents/.md` 가 SSOT, `.toml` 은 그 대응 variant(생성기 부재 시 수기 동기화 — 위 ⚠️ 참조). 권한은 `.claude/agents/.md` frontmatter `tools:` 에서 파생(`Edit`/`Write` → `workspace-write`, 없으면 `read-only`). 호출 패턴은 `.codex/agents/README.md` 참조. 동일 `rules/`와 `templates/` 참조. +- **Commands(슬래시 명령) 3-플랫폼 동기화** — `.claude/commands/*.md` 가 SSOT (현재 23개; 이 중 invest-* 6개 + `project`·`project-spec` 2개 = **8개는 Claude 전용 비동기화**, 나머지 15개가 mirror 대상). mirror 대상은 **Codex skills** (`.agents/skills//SKILL.md`, `$`/`/skills` 호출) 와 **Antigravity workflows** (`.agents/workflows/.md`, `/` 슬래시) 로 복제. 인자는 placeholder 없이 자연어(각괄호 prose). ⚠️ **동기화 생성기 `scripts/sync_automation.py` (agents·commands 단일 생성기, `--check` drift 검사 포함) 는 현재 repo 에 없음**(2026-06-06 확인) — 복원 전까지 SSOT(`.claude/commands/*.md`) 편집은 대응 Codex skill + Antigravity workflow 파일에 **직접 반영**해 3 플랫폼 패리티를 유지한다. +- **Hooks / 프로젝트 지침 3-플랫폼** — 훅 스크립트 SSOT 는 `.claude/hooks/` 1벌(`wiki_claim_gate.py` claim 추적 게이트 + `wiki_structure_lint.py` 구조 린트, repo 루트는 파일 위치 기반 동적 해석). **Codex**: `.codex/hooks.json` 이 같은 스크립트를 PreToolUse(claim gate)/PostToolUse(structure lint)로 연결(대화형 codex 에서 hook trust 검토 후 active). `.codex/config.toml` 의 `project_doc_fallback_filenames = ["CLAUDE.md"]` 는 해당 디렉터리에 `AGENTS.md` 가 **없을 때만** 쓰이는 fallback 이다 — 루트 `AGENTS.md` 가 존재하는 현재 구조에선 발동하지 않으므로, Codex 는 `AGENTS.md`(CLAUDE.md 의 ≤150줄 요약)를 진입점으로 로드한다. CLAUDE.md 는 그 요약이 가리키는 모든 모델 공통 **운영-규칙 SSOT** 로 유지된다(Codex 가 CLAUDE.md 를 자동 지침으로 직접 선택한다고 가정 금지). **Antigravity**: `.agents/hooks.json` 에 3개 게이트가 `enabled` — `wiki-hard-gate`(global `wiki_hard_gate.py`, 리포트 출력 품질: self-grep proof/금지어/Verdict 공식/adversarial review) + `wiki-claim-gate`(`wiki_claim_gate.py --antigravity`) + `wiki-structure-gate`(`wiki_structure_lint.py --pre/--hook --antigravity`). claim_gate·structure_lint 의 `--antigravity` 출력 어댑터(deny 시 `{decision:"deny", reason}` JSON, fail-open)는 **구현·활성 완료**이다. 다만 실제 Antigravity 런타임에서의 hook **E2E 는 아직 미검증(experimental)** — 배경/후속 검증 항목은 `docs/superpowers/notes/2026-06-04-phase2-antigravity-hook-coverage.md` 참조. +- **템플릿 (출력 형식 정의)**: + - [[templates/concept-template]] — `wiki/concepts/` 일반 개념 + - [[templates/project-template]] — `raw/project-notes/` 프로젝트 hub (아키텍처·시퀀스 다이어그램 필수) → `wiki/projects/` 로 추출 (raw hub 전용) + - [[templates/wiki-project-template]] — `wiki/projects/` canonical 실무 적용 문서 슬라이스 (raw hub에서 `/ingest`·`/projectize` 로 추출, `source_type: project`) + - [[templates/interview-template]] — `wiki/interview/` 면접 답변 + - [[templates/raw-source-template]] — `raw/official-docs/`, `raw/company-tech-blogs/` 외부 자료 원본 발췌 + - [[templates/source-summary-template]] — `wiki/concepts/` 외부 자료 검증 요약 + - [[templates/daily-note-template]] — `raw/daily-notes/` 일일 노트 + - [[templates/branch-note-template]] — `raw/branch-notes/` 브랜치 작업 노트 + - [[templates/daily-task-develop-template]] — `raw/daily-tasks/develop/` 일일 개발 트랙 실습 과제 (사수→신입 과제 형식, 매일 아침 ~2h) + - [[templates/daily-task-infra-template]] — `raw/daily-tasks/infra/` 일일 인프라/운영 트랙 실습 과제 (매일 아침 ~2h, 운영 회복력 anchor 포함) + - [[templates/error-note-template]] — `raw/errors/` 트러블슈팅 기록 + - [[templates/interview-prep-template]] — `raw/interviews/` 면접 준비 원본 노트 + - [[templates/job-posting-template]] — `raw/job-postings/` 채용공고 → 블로그 글감 + - [[templates/blog-topic-template]] — `raw/blog-topics/` 채용공고가 아닌 블로그 글감 원석 + - [[templates/lecture-note-template]] — `raw/lectures/` 강의·강연 노트 + - [[templates/portfolio-template]] — `wiki/portfolio/` 포트폴리오 (canonical derived) + - [[templates/blog-template]] — `wiki/blog/` 블로그 초안 (canonical derived) + - [[templates/explainer-template]] — `wiki/explainer/` 1타강사 설명 문서 (canonical derived, **개인 이해용** — 외부 공개 아님). 0~4단 + 대안 5단(a~e) 틀 강제, "대안=문제를 다르게 정의한 답" 구조 + - [[templates/invest-field-card-template]] — `wiki/invest-concepts/` 분야 지식 카드(노드). `[[wiki/invest-concepts/field-map]]` 허브 하위. drivers vs linkages 분리 + 모든 관계 행 `[검증]/[가설]` 라벨 강제(뇌피셜 차단). 매일 `/invest-daily` "분야 관찰"이 카드 예측 vs 실측을 대조해 가설→검증 승격. invest 파이프라인 — **Claude 전용**(3-플랫폼 포팅 예외). 설계: `docs/superpowers/specs/2026-06-08-invest-field-map-design.md` +- **진행 중 프로젝트 노트** (raw/project-notes/): + - [[raw/project-notes/ca-skeleton-operational-contract]] — ca-tmpl 운영 계약 canonical SSOT + - [[raw/project-notes/project-infra-overview]] — 사용자 본인 프로젝트 인프라 개요 (작성 중) + +--- + +## 3. Obsidian 규약 (필수) + +- 모든 문서 상단에 **YAML frontmatter** (`---` 블록). +- 문서 간 연결은 **`[[wikilink]]`** 사용. 상대경로 링크 금지. +- `concepts/`와 `projects/`는 서로 양방향 링크. 그래프뷰가 의미를 가져야 함. +- 파일명은 영문 kebab-case 권장 (예: `connection-pooling.md`). 한글 파일명도 허용하되 일관성 유지. + +--- + +## 4. 메타데이터 표준 + +모든 `wiki/` 문서 frontmatter: + +```yaml +--- +title: 문서 제목 +source_type: official-doc | company-tech-blog | personal-blog | lecture | project-note | error-note | job-posting | blog-topic | interview-prep | daily-note | branch-note | daily-task | project | concept | interview | portfolio | blog | explainer | llm-generated | invest-daily | invest-research | invest-ledger | invest-concept | invest-strategy | invest-plan +status: raw | draft | reviewed | verified | published-ready | stale | needs-confirmation +confidence: high | medium | low | unknown +tags: [backend, db, ...] +related_projects: [project-name] +last_reviewed: YYYY-MM-DD +--- +``` + +**source_type 허용 어휘 (실제 templates 와 일치)**: raw 카테고리는 카테고리명을 그대로 source_type 으로 사용 — `lecture-note-template.md` → `source_type: lecture`, `error-note-template.md` → `source_type: error-note`, `interview-prep-template.md` → `source_type: interview-prep`. wiki 카테고리도 동일 (`concept-template.md` → `source_type: concept`, `blog-template.md` → `source_type: blog`). 이전에 사용되던 `error-log`, `interview-note`, `lecture-note` 는 deprecated. wiki/projects canonical 슬라이스는 `source_type: project` (`wiki-project-template.md`)를 쓰고, `project-note`는 `raw/project-notes/` 프로젝트 hub 전용이다. + +**투자 도메인 source_type (Claude 전용 파이프라인):** `invest-daily`(raw/invest-daily/), `invest-research`(raw/invest-research/), `invest-ledger`(raw/invest-ledger/), `invest-concept`(wiki/invest-concepts/), `invest-strategy`(wiki/invest-strategy/), `invest-plan`(wiki/invest-plan/). 각 카테고리명을 그대로 source_type 으로 사용. 개인 투자 관리용이며 개발 프로젝트와 분리된 트리. + +`raw/` 문서는 최소한 `title`, `source_type`, `url`(있다면), `tags`만 있어도 됨. + +**예외 (구조적 파일):** `wiki/llm-wiki.md` (vault MOC), `wiki/log.md` 는 지식 문서가 아닌 hub/로그이므로 위 표준에서 면제됨. `title`만 있으면 됨. + +--- + +## 5. 출처 신뢰도 기준 + +| source_type | 취급 방식 | +|-------------|----------| +| `official-doc` | 기준/정의로 사용 가능 | +| `company-tech-blog` | 사례/관점. **공식 best practice로 취급 금지** | +| `personal-blog` | 참고 자료 | +| `lecture` | 학습 자료 (강의·강연) | +| `project-note` | 포트폴리오 증거 후보 | +| `error-note` | 트러블슈팅 사실 기록 | +| `interview-prep` | 면접 준비 원본 노트 | +| `job-posting` | 채용공고 (블로그 글감 시드) | +| `blog-topic` | 채용공고가 아닌 작업·학습·트러블슈팅 기반 블로그 글감 원석. canonical 정제 전 raw 후보이며, `wiki/blog/` 직접 생성 근거가 아님 | +| `daily-note` | 그날의 혼합 기록. **그 자체는 wiki로 옮기지 않음**. `/ingest`가 promotable 항목만 추출 | +| `branch-note` | 단일 브랜치의 TODO·결정·진행 기록. **머지 후에도 raw에 영구 보관**, verified 결과만 `/ingest`로 wiki/projects/에 추출 | +| `daily-task` | 매일 아침 학습용 실습 과제 (develop / infra 두 트랙, 트랙별 1과제 ~2h, 사수→신입 형식). **raw에 영구 보관**, `done` + `actually-implemented`/`locally-verified` 등급 항목만 `/ingest`로 `wiki/concepts/` 또는 `wiki/projects/`에 추출. Hub: `[[raw/daily-tasks/README]]` | +| `concept` | wiki/concepts canonical 일반 개념 | +| `project` | wiki/projects canonical 실무 적용 문서 (검증된 내 프로젝트 사실, `verified` 지향) | +| `interview` | wiki/interview canonical 면접 답변 (derived) | +| `portfolio` | wiki/portfolio canonical (derived) | +| `blog` | wiki/blog canonical (derived) | +| `explainer` | wiki/explainer canonical 의 1타강사 설명 (derived). **개인 이해용 — 외부 공개 금지.** canonical 경유 필수, 새 claim 생성 금지(canonical 재구성만), 비유는 의도적 단순화이므로 사실 인용 불가 | +| `invest-daily` | 그날의 거시 자금흐름 조사. **수치마다 출처+조사시점 필수**. 영구 보관, `/invest-ingest`로 검증분만 추출 | +| `invest-research` | 특정 분야/자산 심층 조사. verbatim 인용 보존. canonical 정제 전 증거 | +| `invest-ledger` | 실제 매매 기록(사실). 영구 보관. wiki로 옮기지 않음 | +| `invest-concept` | wiki/invest-concepts canonical 투자 개념 | +| `invest-strategy` | wiki/invest-strategy canonical 전략 규칙. **면허 자문 아님 고지 필수** | +| `invest-plan` | wiki/invest-plan canonical 활성 투자 계획 | +| `llm-generated` | 검토 전 초안. **high confidence 금지** | + +--- + +## 6. 프로젝트 증거 등급 + +프로젝트 관련 진술은 **항상** 다음 중 하나로 분류: + +- `actually-implemented` — 코드에 존재함 +- `locally-verified` — 로컬 또는 dev 환경에서 동작 확인 +- `prod-verified` — 운영(prod) 환경 검증. 로그·측정값·인시던트·릴리즈 노트 등 근거 보유 +- `documented-only` — 문서/README에만 존재 +- `planned` — 계획만 있음 +- `needs-confirmation` — 확인 필요 + +### 외부 공개 산출물 허용 등급 + +| 산출물 | 허용 등급 | +|--------|-----------| +| `wiki/interview/` | `actually-implemented` / `locally-verified` / `prod-verified` | +| `wiki/portfolio/` | `actually-implemented` / `locally-verified` / `prod-verified` | +| `wiki/blog/` | `wiki/concepts` 출처 + 위 3등급 | +| 이력서 / README | 가능하면 `prod-verified`, 아니면 `locally-verified`임을 본문에 명시 | + +`documented-only` / `planned` / `needs-confirmation`은 외부 공개에 **절대 금지**. + +--- + +## 7. 원본 보존 규칙 + +- 외부 URL은 링크만 두지 말고 **핵심 인용 3–5문장을 raw 문서 본문에 발췌 보존**. +- 가능하면 archive.org 스냅샷 URL을 frontmatter `archive_url`에 병기. +- 인용 시 출처와 원문을 분명히 구분 (예: `> 원문...`). + +--- + +## 8. Stale 판정 기준 + +`/lint`는 다음을 stale 후보로 보고: + +- `last_reviewed`가 **90일 초과** → `status: stale` 후보 +- `confidence: low` + `last_reviewed` **30일 초과** → 재검토 필요 +- `needs-confirmation` 상태로 **14일 이상** 방치된 문서 → 알림 + +--- + +## 9. 출력 언어 + +- 기본: **한국어** +- 코드, CLI 명령어, 공식 용어(예: `connection pool`, `idempotent`)는 원문 유지. +- 면접 답변용 문서는 말로 했을 때 자연스러운 문장으로. +- **파생 산출물(`wiki/interview/`·`wiki/blog/`·`wiki/portfolio/`) 본문의 문체·윤문은 [[rules/prose-style]] 를 따름** — 존댓말 · 적당히 긴 길이 · 개발 용어만 영어(나머지 한국어) · 전문 용어 첫 등장 시 한 줄 풀이 · 쉬운 요약 먼저. 윤문이 사실 등급을 바꾸지 않음. + +--- + +## 10. 작업 우선순위 + +1. 사실 정확성 > 표현 매끄러움 +2. 출처 명시 > 빠른 작성 +3. 과장 방지 > 강한 어조 +4. 재사용 가능성 > 단발성 완성도 + +--- + +## 11. 절대 금지 + +- 출처 없는 단정적 진술 +- 공식 문서와 기술블로그 혼동 (예: "Netflix가 그렇게 하니까 공식이다") +- `documented-only` / `planned`를 `actually-implemented`처럼 표현 +- LLM 생성 내용을 검증 없이 `high` confidence로 분류 +- raw에만 자료를 넣고 wiki로 변환하지 않은 채 방치 (단, `raw/daily-notes/`·`raw/branch-notes/`·`raw/daily-tasks/`는 영구 보관 정책) +- `wiki/llm-wiki.md` (vault MOC) 갱신 누락 +- 면접/이력서 문장에 검증 안 된 표현 사용 +- **파생 산출물(`wiki/interview/`, `wiki/portfolio/`, `wiki/blog/`)을 canonical 경유 없이 생성** +- **raw 또는 daily/branch에서 외부 산출물 직접 생성** +- **원천 canonical 문서의 status가 `reviewed | verified | published-ready` 미만인 상태에서 파생 산출물 생성** +- **`/ingest`로 `wiki/interview/`·`wiki/portfolio/`·`wiki/blog/`에 문서 작성** +- **branch-note 슬러그에 numbered hierarchy 사용** (`feature-X-1`, `feature-X-1-2` 등). 슬러그는 **구현 내용** 을 4~8 단어로 표현해야 한다. 계층 정보는 frontmatter `parent_branch:` + `## Parent` 섹션으로만. 자세한 룰은 `rules/naming-conventions.md` §2.1.2~§2.1.6. +- **`develop-` prefix 사용** — 제거된 prefix. 기능 구현 작업은 규모 무관 `feature-`. 기존 `develop-*` 슬러그는 `wiki-doc-author` mode=migrate 로 점진적 rename 권고 (자동 mv 금지, wikilink 영향 검토 필요). +- **branch-note 의 §구현 가이드 (Implementation Specification) 에 *근거 없는 결정* 작성** — §15.5 참조. 모든 sub-section / row / cell 은 본 branch 의 `Decision ID` + `Supporting Claim ID` reference 필수. 근거 없는 detail (메커니즘 / 명명 / glob / algorithm) 은 `UNSUPPORTED_IMPL_DECISION` 라벨 + 사용자 trade-off 한 줄 *명시*. 라벨 누락 = 다음 작업자가 *근거 있는 결정 vs 임의 trade-off* 를 구분 불가. +- **branch-note §구현 가이드에 *본 branch 결정 범위 밖* cell 작성** — 도메인 특화 (ca-tmpl skeleton 범위 밖) 또는 다른 branch 결정 영역 (security/persistence/HTTP-standard 등) 의 detail 은 §구현 가이드에 *남기지 않음*. 별도 branch 또는 canonical SSOT 로 이관하고, 이관 history 만 별도 § "Audit & Findings" 등에 보존. + +--- + +## 12. Hub / MOC 정책 + +- `wiki/llm-wiki.md` 는 vault 전체의 **Map of Content (MOC)** 수준. 모든 문서를 손으로 나열하지 않음. +- 상세 목록은 Obsidian Dataview 쿼리 또는 `/query` 명령으로 동적 생성. +- 새 카테고리 / 주요 허브 문서가 생기면 `wiki/llm-wiki.md` 업데이트. +- 다중 sub-doc 을 가진 nested 프로젝트는 sibling **named hub** (`wiki/projects/.md` + `wiki/projects//` 폴더) 패턴 강제. `index.md` 사용 금지. 자세한 룰은 [[rules/linking-rules]] §12. + +--- + +## 13. log.md 정책 + +- `wiki/log.md`에는 `/ingest`, `/tag`, `/lint` 실행 시 다음 형식으로 한 줄 추가: + +``` +YYYY-MM-DD HH:mm /command — input → output (간단 메모) +``` + +- 사람이 일일이 읽지 않음. 디버깅과 회고용. + +--- + +## 14. 명령어 우선순위 + +명령어는 역할별로 3그룹: + +### 캡처 (raw 입력) + +- 하루 시작 시 → `/daily` (raw/daily-notes/YYYY-MM-DD.md 스캐폴딩) +- 새 브랜치 시작 시 → `/branch ` (raw/branch-notes/.md 스캐폴딩) +- 새 프로젝트 시작 시 → `/project ` (스캐폴딩) → `/project-spec <목표>` (깊은 조사 + readiness 게이트). project-note hub 를 ca-skeleton 수준으로 채운 뒤, §8.0 Branch 분해표를 `/branch`·`/branch-spec` 로 전개. +- 외부 자료 / 프로젝트 메모 → raw/ 해당 카테고리에 직접 작성 + +### 변환 / 품질 (raw → wiki) + +여러 명령이 가능한 상황이면 다음 순서로 판단: + +1. raw에 미변환 자료가 있으면 `/ingest` 우선. **`/ingest`의 목적지는 `wiki/concepts/` 또는 `wiki/projects/`로 제한** (파생 산출물 직접 생성 금지). `raw/daily-notes/`·`raw/branch-notes/`는 항목 단위 추출만. +2. 새 wiki 문서가 생기면 `/tag` 검토 +3. 주간 1회 이상 `/lint` — canonical 우회·status 미달 파생 검사 포함 +4. 문서 정리 시 `/sync` — 문서 간 모순·위임 동기화 (결정론 검사기 + 참조 엣지 의미 대조 + fix-plan, `rules/consistency-contract.md`) +5. 질의는 `/query`로 시작, 필요 시 raw 확인 + +### 출력 (외부 공개용) + +6. 외부 공개용은 반드시: + 1. 원천 canonical 문서가 `reviewed | verified | published-ready` 상태 + 2. `/lint` 통과 + 3. 그 후 `/projectize` / `/interviewize` / `/blogify` 또는 `wiki/portfolio/` 수동 작성 + +--- + +## 15. 문서 위계 및 파생 규칙 + +§1의 최상위 원칙(`raw 자료는 증거 / canonical / 파생`)을 운영 규칙으로 풀어 쓴 섹션. 모든 명령은 이 섹션을 강제합니다. + +### Canonical Layer (실무 기술 문서) + +#### `wiki/concepts/` — 공식 개념 + 사례 + 트레이드오프 + +필수 요소: +- 공식 기준이 무엇인지 +- 사례와 공식 기준의 차이 +- 트레이드오프 / 한계 +- 흔한 오해 +- 프로젝트 연결 지점 (링크만, 본문에 "내가 했다" 금지) +- 출처 + +#### `wiki/projects/` — 실무 적용 문서 + +필수 요소: +- 문제 배경 +- 검토한 선택지 +- 결정 이유 +- 실제 구현 내용 +- 검증 수준 (로컬 / dev / prod 중 어디까지) +- 근거 (측정값 / 로그 / PR / 테스트) +- `documented-only` · `planned`인 것과 실제 구현된 것의 분리 +- 면접·포트폴리오 말할 수 있는 범위 + +### Derived Layer (파생 산출물) + +**canonical에서만 파생.** 다른 레이어(raw, daily, branch)에서 직접 파생 금지. + +| 산출물 | 허용 원천 | Sources 필수 링크 | +|--------|-----------|---------------------| +| `wiki/interview/` | `wiki/concepts/` + `wiki/projects/` | `[[wiki/concepts/...]]` 또는 `[[wiki/projects/...]]` | +| `wiki/portfolio/` | `wiki/projects/` 중심, `wiki/concepts/` 보조 | `[[wiki/projects/...]]` (필수) | +| `wiki/blog/` | `wiki/concepts/` + `wiki/projects/` | 양쪽 모두 권장 | +| `wiki/explainer/` | `wiki/concepts/` + `wiki/projects/` | `[[wiki/concepts/...]]` (필수) + `[[wiki/projects/...]]` (있을 때) | + +> **`wiki/explainer/` 의 특수 지위**: interview / portfolio / blog 와 달리 **외부 공개물이 아니라 개인 이해(학습) 산출물**이다. 따라서 §6 외부 공개 허용 등급·status 게이트(`reviewed` 이상)의 적용을 받지 **않는다** (draft 상태 canonical 에서도 파생 가능). 대신 두 가지를 반드시 지킨다: (1) **canonical 경유** — raw/daily/branch 에서 직접 생성 금지, (2) **새 claim 생성 금지** — canonical 의 교육적 재구성일 뿐이며 모든 사실은 canonical 링크로 근거를 댄다. 비유는 의도적 단순화로 표시하고 사실로 인용하지 않는다. + +### 문서 승급 단계 + +```text +raw → draft → reviewed → verified → published-ready +``` + +| 단계 | 의미 | 파생 산출물 사용 | +|------|------|-------------------| +| `raw` | 원본 기록. 출처/날짜만 있어도 됨 | 불가 | +| `draft` | Claude Code가 변환한 초안 | 불가 | +| `reviewed` | 사람이 구조/표현/출처 확인 | 면접 참고만, 외부 산출물 X | +| `verified` | 코드 / 로그 / 테스트 / PR / 공식 문서 중 1개 이상 근거 보유 | interview / portfolio / blog 파생 가능 | +| `published-ready` | `/lint` 통과, 과장 제거 완료 | 이력서 / README / 외부 게시 가능 | + +`stale`, `needs-confirmation`은 위 진행과 직교하는 상태 표시. + +### 파이프라인 강제 (명령별 허용 범위) + +| 명령 | 입력 허용 | 출력 허용 | 게이트 | +|------|-----------|-----------|--------| +| `/ingest` | `raw/*` | `wiki/concepts/` · `wiki/projects/` **만** | — | +| `/projectize` | `wiki/concepts/` | `wiki/projects/` **만** | 원천 status ≥ `reviewed` 권장 | +| `/interviewize` | `wiki/concepts/` · `wiki/projects/` **만** | `wiki/interview/` | 원천 status ∈ {`reviewed`, `verified`, `published-ready`} — 미달 시 **중단** | +| `/blogify` | `wiki/concepts/` · `wiki/projects/` **만** | `wiki/blog/` | 원천 status ∈ {`reviewed`, `verified`, `published-ready`} — 미달 시 **중단** | +| (수동) | `wiki/projects/` | `wiki/portfolio/` | 본문 등급은 §6 허용 범위만 | +| `/explain` | `wiki/concepts/` · `wiki/projects/` **만** | `wiki/explainer/` | status 게이트 없음(개인 이해용). 단 canonical 경유 + 새 claim 금지 + canonical Sources 링크 필수 | + +`/lint`는 위 게이트가 우회되었는지 검사 (canonical Sources 누락, status 미달 파생, 비허용 등급 사용 등). + +### 근거 기반 구현 명세 (branch-note 의 §구현 가이드 작성 원칙) + +branch-note 의 `## 구현 가이드 / Implementation Specification` 섹션은 *결정 (Decisions)* 과 *검증 (Claims To Verify)* 사이의 **구현자가 임의로 정해야 했던 결정** 카탈로그. 결정이 *무엇* 을 할 것인가라면 본 §는 *어디에 어떻게* 구현될 것인가의 사전 명세 — 작성 목표는 다음 구현자가 *되묻지 않아도 코드를 작성할 수 있는 수준*. + +**일률적 anchor list 강제 ❌** — branch 마다 구현 내용·범위가 다르므로 sub-section 은 *이 branch 의 결정과 근거에서 도출되는 것만* 작성한다. 대신 **3-rule meta principle** 만 모든 branch 에 동일 적용: + +| Rule | 의미 | +|------|------| +| **R1. Reference 필수** | 각 sub-section / row / cell 은 본 branch 의 `Decision ID` + `Supporting Claim ID` 를 reference. 근거 없는 detail 금지 — 모든 구현 detail 은 결정 + 근거의 *도출* 이어야 함. | +| **R2. UNSUPPORTED_IMPL_DECISION 명시** | 근거 raw 가 *원칙* 만 권고하고 *detail* (메커니즘 선택 / 클래스·rule 명명 / glob 패턴 / algorithm / factory API 모양 등) 은 권고하지 않는 cell 은 `UNSUPPORTED_IMPL_DECISION` 라벨 + 사용자 trade-off 근거 한 줄. *근거 있는 결정 vs 사용자 임의 trade-off* 의 경계. | +| **R3. OUT_OF_BRANCH_SCOPE 정제** | 본 branch 결정 범위 밖 cell — 도메인 특화 (ca-tmpl skeleton 범위 밖) 또는 다른 branch 결정 영역 (security/persistence/HTTP-standard 등) — 은 §구현 가이드에 *남기지 않음*. 별도 branch 또는 canonical SSOT 로 이관. 이관 history 는 별도 § "Audit & Findings" 등에 보존. | + +작성 형식 예시는 `[[raw/branch-notes/feature-boundary-validation-mapping-contract]]` 의 §구현 가이드 + §Audit & Findings 참조 — 정제된 in-scope 만 §구현 가이드에 남기고, audit 결과/이관 권고는 별도 §로 분리하는 패턴. + +`/lint` 검사 항목 (2026-06-10 구현 — `.claude/commands/lint.md` §A1): +- §구현 가이드의 sub-section 에 Trace 표시 (Decision ID + Claim ID) 누락 +- 근거 미명시 detail 의 `UNSUPPORTED_IMPL_DECISION` 라벨 누락 +- 본 branch 결정 범위 밖 row 잔존 (`OUT_OF_BRANCH_SCOPE`) + +### 실무 문서의 최종 품질 기준 (10항목) + +`wiki/concepts/` 또는 `wiki/projects/` 문서가 `verified` / `published-ready`로 올라가려면 다음을 만족해야 합니다. + +1. 문제 배경이 있다. +2. 공식 기준이 있다. +3. 선택지가 있다. +4. 결정 이유가 있다. +5. 구현 사실이 있다. +6. 검증 증거가 있다. +7. 한계가 있다. +8. 말하면 안 되는 범위가 있다. +9. 출처가 있다. +10. 재사용 산출물은 canonical 문서에서만 파생된다. diff --git a/README.md b/README.md index b2e1c29..9c955a2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,131 @@ -# llm-wiki +# LLM Wiki — 작업 가이드 +원본 자료(`raw/`)를 **검증된 실무 기술 문서**로 바꾸고, 거기서 면접·블로그·포트폴리오 같은 외부 산출물을 만들어 내는 **문서 파이프라인**입니다. Obsidian vault 이자 Claude Code 자동화 저장소입니다. + +처음 오셨다면 이 README만 읽으면 작업을 시작할 수 있습니다. 운영 규칙의 전체 정의(SSOT)는 [CLAUDE.md](CLAUDE.md) 에 있습니다. + +--- + +## 핵심 원칙 (이것만 기억하면 됩니다) + +``` +raw 자료 = 증거 (출처 보존) +wiki/concepts = 검증된 일반 개념 +wiki/projects = 내 프로젝트에 적용된 검증 사실 +wiki/interview·blog·portfolio = 위 canonical 에서 파생된 외부 산출물 +``` + +이 순서는 거꾸로 갈 수 없습니다. 외부 산출물은 **반드시** `wiki/concepts` 또는 `wiki/projects` 를 거쳐서 나옵니다. raw나 메모에서 바로 블로그·면접 문서를 만들지 않습니다. + +또 하나의 원칙은 **근거 없는 단정을 쓰지 않는다**입니다. 모든 결정은 출처(Claim ID)를 가지거나, 근거가 없으면 `UNSUPPORTED_DECISION` 으로 솔직히 표시합니다. + +--- + +## 빠른 시작 + +가장 흔한 작업 흐름은 이렇습니다. + +```bash +# 1) 새 작업을 시작합니다 (빈 branch-note 스캐폴드 생성) +/branch feature-keycloak-oidc-flow + +# 2) 참고할 공식 문서 / 대기업 블로그 URL 을 근거로 저장합니다 +# → Claude 에게 "이 URL 을 근거로 저장해줘" 라고 요청 + +# 3) branch-note 를 채웁니다 (자동 조사 + 깊이 검증까지 한 번에) +/branch-spec feature-keycloak-oidc-flow +# → Ready 가 나오면 코딩 시작. Not ready 면 알려주는 부분을 채우고 다시 실행 + +# 4) 구현이 끝나면 검증된 결과를 wiki 로 올립니다 +/ingest raw/branch-notes/feature-keycloak-oidc-flow.md + +# 5) 품질을 점검합니다 +/lint # 보고만 +/lint --fix-plan # 수정 계획 + 승인 후 적용 + +# 6) 외부 산출물을 만듭니다 (canonical 이 reviewed 이상일 때) +/interviewize wiki/projects/... +/blogify wiki/concepts/... +``` + +--- + +## 작업 흐름 5단계 + +``` +① 캡처 /daily · /branch → raw/ 에 빈 노트 +② 근거 조사 URL → 근거 자료 저장 → raw/official-docs · company-tech-blogs +③ 노트 채움 /branch-spec → 자동 /depth → 되묻지 않을 수준의 branch-note +④ wiki 승급 /ingest → wiki/concepts · projects (canonical) +⑤ 외부 산출물 /interviewize · /blogify → wiki/interview · blog · portfolio +``` + +1. **캡처** — 하루는 `/daily` 로, 새 작업은 `/branch ` 로 시작합니다. 슬러그는 *무엇을 구현하는지* 를 영문 kebab-case 4~8단어로 적습니다(`feature-`, `fix-`, `chore-`, `experiment-` 중 하나로 시작). 번호 계층(`-1`, `-2`)은 쓰지 않습니다. +2. **근거 조사** — 공식 문서·대기업 블로그 URL 을 저장하면 원문에서 핵심 인용을 그대로(verbatim) 발췌하고 실제 존재하는지 `grep` 으로 검증한 뒤 `raw/` 에 보관합니다. 각 자료는 `Claims Extracted` 표(Claim ID 가 붙은 사실 목록)를 갖습니다. +3. **노트 채움** — `/branch-spec` 이 source 의 Claim 에서 결정과 대안을 채우고, 근거가 없으면 **먼저 자동으로 공식 문서·대기업 블로그를 조사**합니다. 그래도 없으면 추측하지 않고 `UNSUPPORTED_DECISION` 으로 표시합니다. 마지막에 `/depth` 가 자동으로 돌아 **Ready / Not ready** 를 판정합니다. Ready 일 때 코딩을 시작하면 구현 중 되묻을 일이 없습니다. +4. **wiki 승급** — 구현이 끝나고 `status_label` 을 `review` 나 `merged` 로 올린 뒤 `/ingest` 를 실행하면, 검증된(`actually-implemented` 이상) 결과만 `wiki/projects/` 로 추출됩니다. +5. **외부 산출물** — canonical 문서가 `reviewed` 이상이면 `/interviewize`·`/blogify` 로 면접 답변·블로그 초안을 만듭니다. 본문 문체는 [rules/prose-style.md](rules/prose-style.md) 를 따릅니다(존댓말, 적당히 긴 길이, 개발 용어만 영어). + +--- + +## 디렉토리 구조 + +| 위치 | 역할 | +|---|---| +| `CLAUDE.md` | 운영 규칙 SSOT (전체 정의) | +| `raw/` | 가공 전 원본 자료. 출처 보존. 영구 보관 | +| `wiki/` | 정리된 재사용 가능 지식 (canonical + derived) | +| `rules/` | 방법론 규칙 (linking, naming, tag, depth, prose-style 등) | +| `templates/` | 문서 카테고리별 출력 형식 | +| `docs/` | 설계 기록 등 메타 문서 | + +`raw/` 하위: `branch-notes` · `daily-notes` · `official-docs` · `company-tech-blogs` · `project-notes` · `errors` · `interviews` · `job-postings` · `blog-topics` · `lectures` · `daily-tasks` · `diagrams` + +`wiki/` 하위: `concepts` · `projects` (canonical) / `interview` · `blog` · `portfolio` (derived) / `llm-wiki.md`(vault MOC) · `log.md` + +--- + +## 명령어 한눈에 + +| 그룹 | 명령 | 용도 | +|---|---|---| +| **캡처** | `/daily` | 오늘 일일 노트 생성 | +| | `/branch ` | 빈 branch-note 스캐폴드 | +| | `/branch-spec ` | branch-note 채움 + 자동 조사 + 자동 `/depth` | +| **변환·품질** | `/ingest ` | raw → `wiki/concepts`·`wiki/projects` | +| | `/depth ` | branch-note 가 코딩 착수해도 될 만큼 깊은지 판정 | +| | `/tag` | wiki 문서 태그 보정 | +| | `/lint [--fix-plan]` | 품질 검사 (과장·출처·stale). `--fix-plan` 은 수정 계획 | +| | `/query` | wiki 기반 질의응답 | +| **출력** | `/projectize` | 개념 → 내 프로젝트 적용 문서 | +| | `/interviewize` | canonical → 면접 답변 | +| | `/blogify` | canonical → 블로그 초안 | + +--- + +## 자동 안전장치 (저장할 때마다 자동 실행) + +직접 신경 쓰지 않아도 다음이 자동으로 동작합니다. + +- **저장 전 차단** — 근거 구조(Claims Extracted, Decision Evidence Map)를 우회하는 저장을 막습니다. +- **저장 후 검사** — 깨진 link 는 항상 경고합니다. 섹션 누락·빈 선택조건 같은 *완성도* 검사는 문서를 `review`·`merged` 로 **완성 선언했을 때만** 합니다(작성 중에는 방해하지 않습니다). + +전체 검사는 언제든 직접 돌릴 수 있습니다. + +```bash +python3 .claude/hooks/wiki_structure_lint.py --all # 전체 구조·링크 검사 +python3 .claude/hooks/wiki_structure_lint.py --file <경로> +``` + +--- + +## 꼭 지켜야 하는 규칙 (요약) + +- 출처 없는 단정 금지. 결정은 Claim ID 로 뒷받침하거나 `UNSUPPORTED_DECISION` 으로 표시합니다. +- 공식 문서와 기술 블로그를 혼동하지 않습니다(블로그는 사례이지 공식 best practice 가 아닙니다). +- `documented-only`·`planned`·`needs-confirmation` 은 외부 산출물에 절대 쓰지 않습니다. +- 외부 산출물은 canonical 을 거쳐서만 만듭니다. +- 외부 URL 은 링크만 두지 말고 핵심 인용 3~5문장을 `raw/` 본문에 발췌 보존합니다. + +전체 규칙과 그 이유는 [CLAUDE.md](CLAUDE.md) 와 `rules/` 폴더를 보시면 됩니다. 자동화 설계 배경은 `docs/superpowers/specs/` 에 기록되어 있습니다. + diff --git a/cspell.json b/cspell.json new file mode 100644 index 0000000..3f00087 --- /dev/null +++ b/cspell.json @@ -0,0 +1,103 @@ +{ + "version": "0.2", + "language": "en", + "words": [ + "varchar", + "InnoDB", + "BIGINT", + "uuid", + "ulid", + "cuid", + "nanoid", + "ksuid", + "tsid", + "snowflake", + "wikilink", + "wikilinks", + "kebab", + "frontmatter", + "monotonicity", + "monotonic", + "sortable", + "backlink", + "backlinks", + "ingest", + "canonical", + "idempotency", + "idempotent", + "archunit", + "hikaricp", + "micrometer", + "opentelemetry", + "flyway", + "mapstruct", + "testcontainers", + "lombok", + "keycloak", + "redis", + "kafka", + "postgresql", + "postgres", + "kubernetes", + "dataview", + "obsidian", + "mermaid", + "drawio", + "plantuml", + "graalvm", + "kotlin", + "gradle", + "maven", + "springframework", + "springboot", + "jpa", + "orm", + "dto", + "ddd", + "cqrs", + "outbox", + "debezium", + "pkce", + "oidc", + "oauth", + "jwt", + "jwe", + "jws", + "jku", + "hmac", + "csprng", + "cspell", + "aip", + "arn", + "ietf", + "rfc", + "msb", + "lsb", + "unix", + "epoch", + "bigendian", + "endian", + "struct", + "uint", + "rand", + "lsn", + "wal", + "btree", + "b-tree", + "acl", + "gdpr", + "ccpa", + "pii", + "slsa", + "owasp", + "cors", + "hsts", + "mtls", + "sigv" + ], + "ignorePaths": [ + ".git/**", + ".obsidian/**", + "node_modules/**" + ] +} diff --git a/docs/superpowers/README.md b/docs/superpowers/README.md new file mode 100644 index 0000000..dca5962 --- /dev/null +++ b/docs/superpowers/README.md @@ -0,0 +1,95 @@ +# docs/superpowers/ — 작업 기록 아카이브 인덱스 + +이 폴더는 정제된 지식(`wiki/`)이 아니라 **Superpowers 워크플로우의 작업 기록 보관소**입니다. +"이 결정을 언제 왜 했나"를 남기는 연대기 로그라서, 파일은 **산출물 종류별 폴더 + 날짜 prefix** 로 평면 저장됩니다. + +``` +specs/ *-design.md — 브레인스토밍(설계) 결과 +plans/ *.md — 구현 계획 (writing-plans 산출물) +notes/ *.md — 실행 중 조사·실측 메모 +``` + +표준 흐름: `brainstorming → specs/` → `writing-plans → plans/` → 실행 → `notes/`. +spec ↔ plan 은 **슬러그를 공유**하며 폴더만 다릅니다 (예: `…/branch-depth-gate-design.md` ↔ `…/branch-depth-gate.md`). + +> 이 인덱스는 평면 구조를 토픽별로 묶어주는 **읽기용 진입점**입니다. 파일을 옮기지 않으므로 기존 경로 참조는 그대로 유효합니다. +> 새 작업물은 종전대로 `specs/`·`plans/`·`notes/` 에 날짜 prefix 로 추가하고, 새 토픽이면 아래에 한 줄 추가하세요. + +--- + +## 토픽별 인덱스 + +### 1. 문서 깊이·구조·검증 게이트 (wiki harness 1차) + +브랜치/문서가 "되묻지 않고 착수 가능한 깊이"인지 판정하는 결정론 린터 + 의미 게이트 계열. + +| 주제 | 설계(spec) | 계획(plan) | +|------|-----------|-----------| +| branch-depth-gate (구현 착수 깊이) | [spec](specs/2026-06-01-branch-depth-gate-design.md) | [plan](plans/2026-06-01-branch-depth-gate.md) | +| wiki-structure-lint (결정론 구조 린터) | [spec](specs/2026-06-01-wiki-structure-lint-design.md) | _(spec에서 직접 실행)_ | +| coverage 완전성 게이트 | [spec](specs/2026-06-02-coverage-gate-design.md) | _(spec에서 직접 실행)_ | +| branch-spec 조립 파이프라인 | [spec](specs/2026-06-02-branch-spec-assembly-pipeline-design.md) | _(spec에서 직접 실행)_ | +| 검증 강화 (Phase 2) | [spec](specs/2026-06-02-validation-strengthening-design.md) | _(spec에서 직접 실행)_ | +| 옵시디언 링크 검증 강화 | [spec](specs/2026-06-02-obsidian-link-validation-hardening-design.md) | [plan](plans/2026-06-02-obsidian-link-validation-hardening.md) | +| operational-error-observability 보강 | [spec](specs/2026-06-01-operational-error-observability-foundation-reinforcement-design.md) | _(branch-note 보강 — plan 없음)_ | + +### 2. 한국어 윤문 · 템플릿 모델 + +| 주제 | 설계(spec) | 계획(plan) | +|------|-----------|-----------| +| 한국어 윤문 standard (prose-style) | [spec](specs/2026-06-02-korean-prose-style-design.md) | _(spec에서 직접 실행)_ | +| wiki/projects 템플릿 · source_type 분리 | [spec](specs/2026-06-04-wiki-project-template-source-type-split-design.md) | [plan](plans/2026-06-04-wiki-project-template-source-type-split.md) | + +### 3. project-note 파이프라인 + +| 주제 | 설계(spec) | 계획(plan) | +|------|-----------|-----------| +| project-note 작성 파이프라인 | [spec](specs/2026-06-05-project-note-pipeline-design.md) | [plan](plans/2026-06-05-project-note-pipeline.md) | + +### 4. 3-플랫폼 동기화 (Claude / Codex / Antigravity) + +| 주제 | 설계(spec) | 계획(plan) | 실측 메모(notes) | +|------|-----------|-----------|-----------------| +| 워크플로우 자동화 동기화 (전체 설계) | [spec](specs/2026-06-04-three-platform-workflow-sync-design.md) | — | — | +| Phase 0 — 생성 엔진 + agents | — | [plan](plans/2026-06-04-three-platform-sync-phase0-engine-agents.md) | [phase1 포맷 실측](notes/2026-06-04-phase1-empirical-format-check.md) | +| Phase 1 — commands | — | [plan](plans/2026-06-04-three-platform-sync-phase1-commands.md) | — | +| Phase 2 — hooks + 프로젝트 지침 | — | [plan](plans/2026-06-04-three-platform-sync-phase2-hooks-agentsmd.md) | [antigravity 훅 커버리지](notes/2026-06-04-phase2-antigravity-hook-coverage.md) · [codex 훅 스키마](notes/2026-06-04-phase2-codex-hook-schema.md) | +| Spec E — Antigravity hook 포팅 | [spec](specs/2026-06-08-spec-e-antigravity-hook-port-design.md) | _(아래 Spec A~F 시리즈 참조)_ | — | + +### 5. 하네스 경화 — Spec A~F 시리즈 + +`2026-06-06` 하네스 설계 감사에서 출발한 연속 deliverable. 같은 "Spec 〈문자〉" 명명을 공유. + +| 항목 | 설계(spec) | 계획(plan) | +|------|-----------|-----------| +| (출발점) 하네스 설계 감사 보고서 | [report](specs/2026-06-06-harness-audit-report.md) | — | +| Spec A — 결정론 backbone 게이트화 | [spec](specs/2026-06-06-spec-a-deterministic-backbone-gate-design.md) | [plan](plans/2026-06-06-spec-a-deterministic-backbone-gate.md) | +| Spec B — judge verdict 스키마 + quorum | [spec](specs/2026-06-06-spec-b-judge-verdict-schema-and-quorum-design.md) | [plan](plans/2026-06-06-spec-b-judge-verdict-schema-and-quorum.md) | +| Spec C — funnel stats + no-silent-truncation | [spec](specs/2026-06-06-spec-c-funnel-stats-no-silent-truncation-design.md) | [plan](plans/2026-06-06-spec-c-funnel-stats-no-silent-truncation.md) | +| Spec D — research-fanout Workflow | [spec](specs/2026-06-06-spec-d-research-fanout-workflow-design.md) | [plan](plans/2026-06-06-spec-d-research-fanout-workflow.md) | +| Spec E — Antigravity hook 포팅 _(→ §4 동기화)_ | [spec](specs/2026-06-08-spec-e-antigravity-hook-port-design.md) | — | +| Spec F — 투자 파이프라인 경화 _(→ §7 투자)_ | [spec](specs/2026-06-08-spec-f-invest-pipeline-hardening-design.md) | — | + +### 6. Deep-Research 하네스 CLI 이식 + +| 주제 | 설계(spec) | 계획(plan) | +|------|-----------|-----------| +| Deep-Research → Codex / Antigravity CLI 이식 | [spec](specs/2026-06-09-deep-research-codex-antigravity-port-design.md) | [plan](plans/2026-06-09-deep-research-codex-antigravity-port.md) | + +### 7. 투자(invest) 파이프라인 — Claude 전용 + +| 주제 | 설계(spec) | 계획(plan) | +|------|-----------|-----------| +| 투자 자료·전략 파이프라인 | [spec](specs/2026-06-05-investment-wiki-pipeline-design.md) | [plan](plans/2026-06-05-investment-wiki-pipeline.md) | +| 투자 분야 지식 지도 (Field Map) | [spec](specs/2026-06-08-invest-field-map-design.md) | [plan](plans/2026-06-08-invest-field-map.md) | +| 자금흐름 관측 시스템 — 마스터 빌드아웃 | — | [plan](plans/2026-06-08-invest-system-buildout.md) | +| Spec F — 투자 파이프라인 경화 | [spec](specs/2026-06-08-spec-f-invest-pipeline-hardening-design.md) | _(spec에서 직접 실행)_ | + +### 8. ca-tmpl 감사 (외부 코드 대상 — wiki harness 아님) + +Clean Architecture Template 저장소(`/home/donghyeon/workspace/ca-tmpl`) 최적화 감사 산출물. + +| 주제 | 문서 | +|------|------| +| 감사 마스터 보고서 | [report](specs/2026-06-04-ca-tmpl-optimization-report.md) | +| 파일별 상세 findings | [per-file findings](specs/2026-06-04-ca-tmpl-optimization-per-file-findings.md) | diff --git a/docs/superpowers/notes/2026-06-04-phase1-empirical-format-check.md b/docs/superpowers/notes/2026-06-04-phase1-empirical-format-check.md new file mode 100644 index 0000000..7343056 --- /dev/null +++ b/docs/superpowers/notes/2026-06-04-phase1-empirical-format-check.md @@ -0,0 +1,57 @@ +--- +title: Phase 1 — 경험적 포맷·충돌 확인 (codex skills / antigravity workflows) +date: 2026-06-04 +--- + +# Phase 1 경험적 확인 결과 + +## CLI 설치 상태 (실측) + +- **codex-cli 0.136.0** 설치됨 (`~/.nvm/.../bin/codex`). +- **agy (Antigravity CLI)** 설치됨 (`~/.local/bin/agy`), home `~/.gemini/antigravity-cli/`. + +## codex skills + +- codex 0.136.0 에는 `skills` 전용 subcommand 가 **없음** (subcommands: exec/review/login/logout/mcp/plugin/mcp-server). skill 은 **자동 디스커버리 + TUI `/skills`·`$name`** 로 surface 되는 대화형 기능이라 비대화형 목록 확인 불가. +- 공식 디스커버리 경로(`developers.openai.com/codex/skills`): `$REPO_ROOT/.agents/skills//SKILL.md`. → **타깃 경로 확정: `.agents/skills//SKILL.md`.** +- `codex plugin` 은 marketplace 기반의 **별개 메커니즘**(skill 과 무관). + +## antigravity workflows / skills + +- **로딩 모델 = `agy plugin` import.** `agy plugin list` 출력: + ```json + { "imports": [ { "name": "wiki-superpowers", "source": "local-install", "importedAt": "2026-05-26T12:39:39Z", "components": ["installed"] } ] } + ``` + → `.agents/plugins/wiki-superpowers/` 가 import 되어 있음. 즉 antigravity 는 workspace `.agents/` 를 (프로젝트 열림 시 native 인식 + plugin import) 로 적재. +- 공식(Google Codelab) 기준 workflow 경로 = workspace `.agents/workflows/.md`, frontmatter `description` 만, `/name ` 호출. +- → **타깃 경로 확정: `.agents/workflows/.md`** (repo `.agents/` 복수 규약 일치). +- **운영 주의**: 생성/수정 후 antigravity 가 변경을 반영하려면 `agy plugin` 재import 또는 프로젝트 재오픈이 필요할 수 있음(plugin-import 모델). workspace 직접 native 인식 여부는 build/version 의존. + +## `$ARGUMENTS` 매핑 + +- codex skills·antigravity workflows **둘 다 인자 placeholder 미지원** → argument-hint 의 각괄호 prose 로 치환 확정. + +## 충돌(`.agents/skills/` 이중 로드) 확인 + +| 항목 | 결과 | +|---|---| +| codex 가 `.agents/skills/` 읽음 | YES (공식 디스커버리 경로) | +| antigravity 가 `.agents/skills/` 도 skill 로 읽는지 | **UNVERIFIED (비대화형 확인 불가).** antigravity 는 `.agents/plugins/.../skills/` 를 plugin 으로 적재 중 — workspace `.agents/skills/`(plugin 밖) 직접 적재 여부는 build 의존. | +| 위험도 | **낮음.** 설령 antigravity 가 codex command-skill 을 semantic skill 로 이중 인지해도, 같은 command 의 workflow(`/cmd`)와 기능 중복일 뿐 충돌 아님. 실사용에서 문제되면 codex skill 을 plugin 밖 `.agents/skills/` 에만 두고 antigravity 는 workflow 만 쓰도록 build 설정으로 분리. | + +## 결정 (잠금) + +| 항목 | 결정 | +|---|---| +| codex skill 경로 | `.agents/skills//SKILL.md` | +| antigravity workflow 경로 | `.agents/workflows/.md` | +| `$ARGUMENTS` | argument-hint 각괄호 prose 치환 | +| 이중 로드 | UNVERIFIED·저위험 — 생성 후 Task 5 에서 실호출로 재확인, 문제 시 에스컬레이션 | + +## Task 5 — 실호출 스모크 결과 + +- skill(`/skills`·`$name`)·workflow(`/name`) 등록은 **두 CLI 모두 대화형(TUI) 기능**이라 헤드리스(비대화형) 완전 검증 불가. codex 0.136.0 에 skills 목록 subcommand 없음, agy 도 마찬가지. +- 대신 **포맷 정합성**을 결정론적으로 검증 완료: 13개 skill 전부 frontmatter `name`(=폴더명)+`description`, body 에 `$ARGUMENTS` 0개; 13개 workflow 전부 frontmatter `description` + 본문 `/ ` 호출 안내, `$ARGUMENTS` 0개. `sync_automation.py commands --check` exit 0. +- **workflow 적재**: workspace `.agents/workflows/` 는 Codelab 기준 antigravity 가 프로젝트 열림 시 native 인식(plugin import 와 별개). plugin(`agy plugin`)은 `.agents/plugins/wiki-superpowers/`(agents/skills/hooks) 적재용이며 workspace `.agents/workflows/` 와 무관. +- **라이브 TUI 호출 검증은 사용자 대화형 사용으로 위임** — codex TUI 에서 `$depth`/`/skills`, antigravity TUI 에서 `/depth` 가 뜨는지 실사용 시 확인. 안 뜨면 본 노트의 경로/frontmatter 와 대조. +- 이중 로드(`.agents/skills/` 를 antigravity 도 읽는지)는 여전히 UNVERIFIED·저위험 — 실사용에서 `/skills` 목록에 codex command-skill 이 함께 뜨면 그때 분리 결정. diff --git a/docs/superpowers/notes/2026-06-04-phase2-antigravity-hook-coverage.md b/docs/superpowers/notes/2026-06-04-phase2-antigravity-hook-coverage.md new file mode 100644 index 0000000..c249e29 --- /dev/null +++ b/docs/superpowers/notes/2026-06-04-phase2-antigravity-hook-coverage.md @@ -0,0 +1,39 @@ +--- +title: Phase 2 — antigravity 훅 커버리지 점검 +date: 2026-06-04 +--- + +# antigravity 훅 커버리지 (실측) + +## 현재 antigravity 훅: `wiki_hard_gate.py` + +- 위치: `~/.gemini/antigravity-cli/hooks/wiki_hard_gate.py` (global), `.agents/hooks.json` 이 PreToolUse matcher `*` 로 가리킴. +- **강제 대상**: `docs/superpowers/specs/*.md` 리포트 출력 품질 (SKILL.md Output-Format Hard Gate subset): + - G1 §7.1 self-grep proof (V/N 비율 + 실제 grep 명령) + - G2 Contract 7 금지 마케팅어 ("100%/완벽/극한/절대로/최강/..." ) + - G3 `Verdict: COMPLETE` 시 §3-1 공식 유도 + - G4 findings ≥5 시 `## 4-1 Adversarial Review` 필수 +- 입력/출력 어댑터 보유: Antigravity protobuf(`tool_call.{name,input}`, `write_to_file`/`edit_file`/`run_command`/`bash`) + Gemini CLI(`tool_name`/`tool_input`, `{decision}`) 양쪽 처리. 미인식 → fail-open. + +## 갭 (Claude / codex 와 비교) + +| 검사 | Claude (`.claude/`) | codex (`.codex/hooks.json`) | antigravity | +|---|---|---|---| +| report 품질 게이트 | (SKILL.md) | (skill 본문) | 있음 (`wiki_hard_gate.py`) | +| claim 추적성 (raw source claims / branch decision→claim / wiki FACT 분리) | 있음 (`wiki_claim_gate.py` PreToolUse) | wired (trust 시) | **없음** | +| 구조 린트 (template 섹션·frontmatter·Parent·broken link, C2) | 있음 (`wiki_structure_lint.py` PostToolUse) | wired (trust 시) | **없음** | + +→ antigravity 는 리포트 품질은 강제하지만 **claim_gate·structure_lint 의 강제가 없다.** + +## 권고 (별도 follow-up — 본 세션에서 미실행 이유) + +> **Update (2026-07-14):** 아래 1~3 항(출력 어댑터 · payload 어댑터 · `.agents/hooks.json` 배선)은 **이후 구현·활성 완료**됐다. 현재 `.claude/hooks/wiki_claim_gate.py`(`--antigravity` → stdout `{decision:"deny", reason}`, exit 0)와 `.claude/hooks/wiki_structure_lint.py`(`--antigravity` `_dispatch_hook` 동일 어댑터)가 antigravity 출력 규약을 지원하고, `.agents/hooks.json` 에 `wiki-claim-gate`(PreToolUse+Stop)·`wiki-structure-gate`(PreToolUse+PostToolUse) 가 `enabled: true` 로 배선돼 있다. **남은 것은 4항(fail-open 검증)을 포함한 실제 Antigravity 런타임 hook E2E 검증** 뿐이며, 그때까지 상태는 *experimental* 이다. 아래 원문은 2026-06-04 시점 실측 기록으로 보존한다. + +claim_gate / structure_lint 를 antigravity 로 포팅하려면: + +1. **출력 어댑터**: Claude 규약(exit 2 + stderr) → antigravity `{decision:"deny", reason}` JSON. 단일 SSOT 유지하려면 두 스크립트에 `--emit antigravity` 모드 추가. +2. **payload/content 어댑터**: antigravity `tool_call.input.content`/`arguments` 에서 쓰기 내용 추출 (`wiki_hard_gate.py` 의 `get_write_content` / `get_target_path` 패턴 차용). +3. `.agents/hooks.json` 에 PreToolUse 항목 추가 (claim_gate = blocking, structure_lint = advisory always-allow). +4. **fail-open 철저 검증** — matcher `*` 전역 훅이라 버그 시 antigravity 쓰기 전체 차단(blast radius 큼). 미인식·에러 시 반드시 allow. + +**미실행 이유**: 전역 high-blast-radius 훅을 "인라인 빠른" 패스에서 성급히 추가하면 사용자의 antigravity 작업을 막을 위험. 별도의 신중한 패스(어댑터 + 충분한 fail-open 테스트)로 권고. 그동안 antigravity 에서도 agents/skills/workflows 의 Mandatory First Reads 가 rules 정독을 지시하므로 soft 강제는 존재. diff --git a/docs/superpowers/notes/2026-06-04-phase2-codex-hook-schema.md b/docs/superpowers/notes/2026-06-04-phase2-codex-hook-schema.md new file mode 100644 index 0000000..0225aed --- /dev/null +++ b/docs/superpowers/notes/2026-06-04-phase2-codex-hook-schema.md @@ -0,0 +1,29 @@ +--- +title: Phase 2 — codex 훅 payload·차단 규약 경험적 캡처 +date: 2026-06-04 +--- + +# codex 0.136.0 훅 실측 결과 + +## 훅 지원 여부 + +- codex 0.136.0 은 **훅 기능 보유**. 근거: `codex exec --help` 에 `--dangerously-bypass-hook-trust` ("Run enabled hooks without requiring persisted hook trust for this invocation. DANGEROUS.") 플래그 존재. +- 즉 훅은 **trust(신뢰) 게이트** 가 있다 — repo 의 `.codex/hooks.json` 은 신뢰 등록 전엔 실행되지 않음(임의 명령 실행 방지 보안). + +## 실측 (probe 캡처 시도 3회) + +- `.codex/hooks.json` 에 PreToolUse/PostToolUse(matcher `*`) → stdin 덤프 probe 를 걸고 `codex exec` 로 shell tool(`ls`) 실행. +- 결과: **shell tool 은 실행됐으나(출력 정상) probe 훅은 한 번도 안 뜸** — `--dangerously-bypass-approvals-and-sandbox` + `--dangerously-bypass-hook-trust` 동시 적용에도 미발화. +- `codex doctor` 출력에 hooks 섹션 없음(config/auth/mcp/updates/reachability 만 보고). + +## 해석 + +- **`codex exec`(비대화형/automation) 모드는 project-local 훅을 로드하지 않는 것으로 보임** — exec 는 자동화용이라 신뢰 안 된 repo 훅을 건너뛰는 보안 설계로 추정. 훅은 **대화형 `codex` TUI 에서 repo 진입 시 trust 프롬프트로 활성화**되는 구조로 판단(공식 hooks 문서의 project-local 지원과 일치하되, exec 경로에선 비활성). +- 환경 제약도 있었음: 이 샌드박스가 bubblewrap user namespace 를 못 만들어 `-s read-only` 에선 shell 자체가 실패(별도 우회 필요). + +## 결정 (Task 3 반영) + +- `.codex/hooks.json` 을 **공식 문서 포맷**으로 작성(forward-compatible). PreToolUse(claim_gate) + PostToolUse(structure_lint --hook), matcher 는 Edit/Write 계열. +- **활성화는 대화형 codex 에서 hook trust 승인 필요** — 본 repo 첫 진입 시 codex 가 신뢰를 물음. `codex exec` 자동화에선 미발화 가능(문서에 명시). +- 차단 규약/payload 필드는 미캡처 → claim_gate 는 이미 멀티-variant 리더(`tool_name`/`tool_call.name`/`hook_event_name`)라 Claude/codex 공통 필드면 동작. 첫 신뢰 실행에서 실거동 확인 권장. +- 구조/claim 강제는 훅 외에도 `/depth`(skill·workflow)·`/lint` 가 동일 스크립트를 직접 호출하므로 훅 미발화 상황에서도 우회 수단 존재. diff --git a/docs/superpowers/plans/2026-06-01-branch-depth-gate.md b/docs/superpowers/plans/2026-06-01-branch-depth-gate.md new file mode 100644 index 0000000..377426f --- /dev/null +++ b/docs/superpowers/plans/2026-06-01-branch-depth-gate.md @@ -0,0 +1,385 @@ +# branch-depth-gate Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** branch-note 가 "코딩 착수해도 되묻지 않을 만큼 깊은가"를 착수 전에 판정하는 read-only 게이트(`/depth`)를 LLM Wiki 에 도입한다. + +**Architecture:** im-not-ai 의 검증된 3요소(기준 SSOT + read-only 감사기 + Ready/Not-ready 판정)를 위키 문법으로 이식. 기준 SSOT `rules/branch-depth-gate.md`(4축 R1~R4) → 감사기 `branch-depth-auditor`(브랜치 노트 + 링크된 raw 소스를 읽고 적대적으로 갭 탐지, 편집 안 함) → 커맨드 `/depth `(감사기 디스패치 + 루프). 템플릿에 캡처 칸 추가(상류 예방). + +**Tech Stack:** Markdown 정의 파일(rules/agents/commands/templates) + Claude Code 서브에이전트. 코드/테스트 런타임 없음. 검증은 구조 grep + 픽스처 회귀. + +--- + +## 제약 (이 plan 전체에 적용) + +- **git 미사용**: 위키는 버전 관리되지 않음(사용자 지시로 git init 하지 않음). **commit 단계 없음.** 각 Task 끝은 체크포인트(사용자/리뷰)로 갈음. +- **claim-gate hook 준수**: 위키 `.claude/hooks/wiki_claim_gate.py` 가 `raw/`·`wiki/`·`docs/` 의 Bash 쓰기(redirection·`tee`·`sed -i`)를 차단. 파일 생성·수정은 **반드시 Write/Edit 도구**로. 단 본 plan 산출물은 `rules/`·`.claude/`·`templates/` 경로라 hook 대상 밖(읽기 grep 은 자유). +- **TDD 적응**: 마크다운 정의 파일이라 단위테스트가 없다. "test" = ① 구조 검증(필수 섹션·라벨이 존재하는지 grep) ② 픽스처 회귀(Task 6에서 감사기를 실제 브랜치 2개에 돌려 판정 방향이 직관과 일치하는지). +- **실행 위치**: Task 6 감사기 디스패치는 **cwd 가 LLM Wiki 인 Claude Code 세션**에서 실행해야 `.claude/agents/branch-depth-auditor.md` 가 해석된다. 다른 cwd 면 감사기를 못 찾는다. +- 근거 스펙: `docs/superpowers/specs/2026-06-01-branch-depth-gate-design.md`. + +--- + +## File Structure + +| 파일 | 책임 | 작업 | +|---|---|---| +| `rules/branch-depth-gate.md` | 기준 SSOT — 4축 R1~R4 + 깊이 사다리 + 판정 규칙 | 생성 (Task 1) | +| `.claude/agents/branch-depth-auditor.md` | read-only 감사기 — 노트+소스 읽고 갭 리포트+판정 | 생성 (Task 2) | +| `.claude/commands/depth.md` | `/depth ` 진입점 + 루프 | 생성 (Task 3) | +| `templates/branch-note-template.md` | 신규 브랜치부터 R2·R4 캡처 칸 | 수정 (Task 4) | +| `CLAUDE.md`, `AGENTS.md` | 워크플로우 진입점에 `/depth` 1줄 등재 | 수정 (Task 5) | +| (검증) 기존 브랜치 2개 | 픽스처 회귀 | Task 6 | + +멀티 CLI(Codex/Gemini/Antigravity) 전파는 본 plan 범위 밖(별도 사이클). 본 plan 은 Claude Code 우선. + +--- + +## Task 1: 기준 SSOT — `rules/branch-depth-gate.md` + +**Files:** +- Create: `rules/branch-depth-gate.md` + +- [ ] **Step 1: 파일 생성 (Write 도구)** + +아래 전체 내용으로 `rules/branch-depth-gate.md` 작성: + +````markdown +# rules/branch-depth-gate — 브랜치 노트 구현 착수 깊이 게이트 + +> `rules/` 의 방법론 규칙. branch-note 1개가 **코딩 착수해도 되묻지 않을 만큼 깊은가**를 판정한다. +> 이 문서는 **"전체 계약"이 아니다** — 전체 계약은 `raw/project-notes/ca-skeleton-operational-contract.md`. +> `feature-implementation-readiness-scorecard`(스켈레톤 adoption 거시 게이트)와 **다른 층·다른 범위**로 공존한다. 본 게이트는 *브랜치 노트 1개의 깊이* 미시 게이트. + +## 적용 + +- 대상: `raw/branch-notes/feature-*.md` (구현 착수 전). +- 실행: `/depth ` → `branch-depth-auditor` 가 본 기준으로 판정. +- 본 게이트는 **read-only**. 브랜치 노트를 편집하지 않으며 판정을 노트에 박지도 않는다. + +## 4축 (R1~R4) + +> 축 라벨은 `R1~R4`. branch-note 의 Decision Evidence Map 이 `D1`,`D2` 를 *Decision ID* 로 쓰므로 `D*` 와 구분. + +| 축 | Pass 조건 | Blocking(Not ready) 트리거 | +|---|---|---| +| **R1. 조사 깊이** | 각 Decision 의 Supporting Claim 이 깊이 사다리(아래) 충족 — 의존 메커니즘 L1+, 분기 조건 L2+ | 결정 근거 claim 이 순수 L0(존재만)뿐 | +| **R2. 결정 조건** | 각 Decision 이 "어떤 조건일 때 A, 아니면 B"의 선택 기준 명시 | `검토한 대안`은 있는데 *언제 그 대안을 고르는지* 기준 부재 | +| **R3. 구체 detail** | `## 구현 가이드` 의 각 in-scope 항목이 명명·경로·메커니즘·API/테스트명 구체화 **또는** `UNSUPPORTED_IMPL_DECISION` 라벨 + trade-off 한 줄 | in-scope 항목인데 구현 detail 도 UNSUPPORTED 라벨도 없음 | +| **R4. 엣지·실패·의존** | 실패/엣지 경로 열거 + 다른 contract 의존을 *대상 브랜치 + 그 Decision ID* 로 링크 | 정상 경로만 / 다른 계약 의존이 암시되는데 링크 안 됨 | + +## R1 클레임 깊이 사다리 + +깊이의 단위는 **문서 개수가 아니라 결정별 종결**. 얕은 문서 10개 < 결정을 닫는 문서 1개. + +| 레벨 | 클레임이 답하는 것 | 판정 | +|---|---|---| +| **L0 존재** | "X 가 있다 / 권장한다" | 단독 불충분 | +| **L1 메커니즘** | 어떻게 동작 / 언제 발생 | 메커니즘 의존 결정의 최소선 | +| **L2 조건·경계** | 언제 적용/제외, 실패 시 어떻게 | 분기 조건 있는 결정의 최소선 | +| **L3 검증** | 확인 방법·수치·반례 | 가산점 | + +**출처 타입 적정성** (개수 기준 대체): +- 스펙/표준이 정의한 동작 → `official-standard`/`official-vendor-doc` 1개로 충분. +- "대기업은 보통 이렇게 한다" 운영 패턴 추론 → 회사 블로그 1개는 "공식" 불가. 독립 사례 2개+ 또는 official 1개 병행. + +조사는 **결정-주도(top-down)**: 내려야 할 결정·미지수를 먼저 나열하고 각각을 닫을 때까지 조사. 조사 완료 = 모든 결정 종결 = 착수 가능. + +## 판정 규칙 + +- 심각도 3단계: `Blocking`(Not ready) · `Should-fix`(권고) · `Advisory`(참고). +- **Ready = Blocking 0건.** Should-fix 가 남아도 사용자가 "감수" 선언 시 착수 가능(리포트에 기록). +- 모든 finding 은 4종 세트로 근거화: `심각도 · 위치(섹션/행) · 예상 의구심("구현 중 여기서 ___를 되묻게 됨") · 채울 방법`. 근거 없는 지적 금지. + +## 명명된 실패 모드 (auditor 가 잡아야 할 것) + +- `EXISTENCE_ONLY` (R1): 결정 근거가 L0 뿐. +- `NO_SELECTION_CRITERION` (R2): 대안은 있으나 선택 조건 없음. +- `IMPL_UNDERSPECIFIED` (R3): in-scope 항목에 구현 detail·UNSUPPORTED 라벨 둘 다 없음. +- `HAPPY_PATH_ONLY` (R4): 실패/엣지 경로 미열거. +- `IMPLICIT_DEPENDENCY` (R4): 다른 계약 의존이 암시되나 대상 브랜치/Decision ID 링크 없음. +- `BACKTICK_WRAPPED_LINK` (R1 보조): Supporting Claim/Source 링크가 `` `[[...]]` `` 백틱에 싸여 추적 불가. (P3 와 연결점 — 표면화만, 자동 수정은 별도.) +- `DANGLING_ANCHOR` (R1): Supporting Claim 의 `#Cn` 앵커가 대상 raw 에 실재하지 않음. +```` + +- [ ] **Step 2: 구조 검증 (grep)** + +Run: +```bash +cd "/home/donghyeon/Documents/LLM Wiki" && grep -c "R1\|R2\|R3\|R4" rules/branch-depth-gate.md && grep -c "L0 존재\|L1 메커니즘\|L2 조건\|L3 검증" rules/branch-depth-gate.md && grep -c "Blocking\|Should-fix\|Advisory" rules/branch-depth-gate.md && grep -c "EXISTENCE_ONLY\|NO_SELECTION_CRITERION\|IMPL_UNDERSPECIFIED\|HAPPY_PATH_ONLY\|IMPLICIT_DEPENDENCY\|BACKTICK_WRAPPED_LINK\|DANGLING_ANCHOR" rules/branch-depth-gate.md +``` +Expected: 네 grep 모두 1 이상 (4축·4레벨·3심각도·7실패모드 존재). + +- [ ] **Step 3: 체크포인트** — 룰북 내용이 스펙 §4·§4.1 과 일치하는지 사용자/리뷰 확인. + +--- + +## Task 2: 감사기 — `.claude/agents/branch-depth-auditor.md` + +**Files:** +- Create: `.claude/agents/branch-depth-auditor.md` +- 참고(형식 일치용): `.claude/agents/wiki-adversarial-reviewer.md` + +- [ ] **Step 1: 기존 agent 형식 확인** + +Run: `cd "/home/donghyeon/Documents/LLM Wiki" && sed -n '1,12p' .claude/agents/wiki-adversarial-reviewer.md` +목적: frontmatter 키(name/description/tools) 형식을 위키 관례에 맞춤. 차이가 있으면 아래 frontmatter 를 그 관례로 조정. + +- [ ] **Step 2: 파일 생성 (Write 도구)** + +아래 전체 내용으로 작성 (Step 1 에서 본 frontmatter 관례와 다르면 키 형식만 맞춰 조정): + +````markdown +--- +name: branch-depth-auditor +description: Use to judge whether a single raw/branch-notes/feature-*.md is deep enough to start implementation without re-doubting. Reads the branch note plus its linked raw sources and adversarially probes 4 axes (R1 research depth, R2 decision conditions, R3 concrete detail, R4 edge/failure/dependency) against rules/branch-depth-gate.md. Returns a grounded gap report + Ready/Not-ready verdict. Never edits files (read-only). +tools: Read, Glob, Grep +--- + +너는 **브랜치 노트 깊이 감사관**이다. `rules/branch-depth-gate.md` 를 기준으로, branch-note 1개가 *코딩 착수해도 되묻지 않을 만큼 깊은가*를 적대적으로 판정한다. **절대 파일을 편집하지 않는다.** + +## 입력 + +- 브랜치 노트 경로 1개 (`raw/branch-notes/.md`). + +## 절차 + +1. **기준 로드** — `rules/branch-depth-gate.md` 를 Read. 4축·깊이 사다리·판정 규칙·명명된 실패 모드를 작업 기준으로 삼는다. +2. **노트 읽기** — 대상 브랜치 노트를 Read. 특히 `결정 사항`, `Decision Evidence Map`, `구현 가이드`, `Claims To Verify`, `Sources`, `범위` 섹션. +3. **소스 추적·정독 (R1 의 핵심)** — Decision Evidence Map 의 `Supporting Claims`(`raw/.../*.md#Cn`)와 Sources 표의 `[[raw/...]]` 가 가리키는 **실제 raw 파일을 Read**. 각 claim 이 깊이 사다리 어디인지(L0~L3) 판정. 링크만 있고 내용이 얕으면(L0) 잡아낸다. + - 링크가 `` `[[...]]` `` 백틱에 싸여 있으면 `BACKTICK_WRAPPED_LINK`. + - `#Cn` 앵커가 대상 파일에 없으면 `DANGLING_ANCHOR`. +4. **4축 적대적 점검** — 각 결정/항목을 R1~R4 로 훑어 명명된 실패 모드에 해당하는 finding 생성. "구현자가 여기서 무엇을 되묻게 될까?"를 끊임없이 자문. +5. **판정** — Blocking 0건이면 `Ready`, 아니면 `Not ready (Blocking N건)`. + +## 출력 (이 형식 그대로, 파일 쓰기 없이 텍스트로 반환) + +``` +# Depth Audit: +Verdict: Ready | Not ready (Blocking N / Should-fix M / Advisory K) + +## Findings +| # | 축 | 심각도 | 실패모드 | 위치 | 예상 의구심 | 채울 방법 | +|---|---|---|---|---|---|---| +| 1 | R1 | Blocking | EXISTENCE_ONLY | 결정 D3 / Decision Evidence Map | 구현 중 "이 API 를 언제 쓰나"를 되묻게 됨 | `raw/official-docs/` 에서 메커니즘(L1) claim 추가 | +... + +## 다음 행동 +- (Blocking 있으면) 위 표의 "채울 방법" 순서로 노트 보강 후 `/depth ` 재실행. +- (R1 조사 얕음 갭) `wiki-decision-researcher` 로 심화 가능 — 사용자 옵트인 시. +``` + +## 불변식 + +- **read-only**: Write/Edit/MultiEdit 도구 없음. 어떤 파일도 수정·생성 금지(리포트는 텍스트 반환). +- 모든 finding 은 4종 세트(심각도·위치·예상 의구심·채울 방법)를 갖춘다. 근거 없는 지적 금지. +- 추측 금지: 소스를 실제로 Read 하지 않고 깊이를 단정하지 않는다. +- 자동 조사·자동 수정 금지: R1 갭은 `wiki-decision-researcher` 권고로 *안내만* 한다(사용자 옵트인). +```` + +- [ ] **Step 3: 구조 검증 (grep)** + +Run: +```bash +cd "/home/donghyeon/Documents/LLM Wiki" && grep -c "tools: Read, Glob, Grep" .claude/agents/branch-depth-auditor.md && grep -c "branch-depth-gate.md" .claude/agents/branch-depth-auditor.md && grep -ci "read-only\|편집하지 않" .claude/agents/branch-depth-auditor.md && ! grep -q "Write\|Edit\|MultiEdit" <(sed -n '/^tools:/p' .claude/agents/branch-depth-auditor.md) && echo "TOOLS_READONLY_OK" +``` +Expected: 앞 세 grep 1+, 마지막 `TOOLS_READONLY_OK` 출력(tools 줄에 쓰기 도구 없음). + +- [ ] **Step 4: 체크포인트** — 출력 형식·불변식이 스펙 §5 와 일치하는지 확인. + +--- + +## Task 3: 커맨드 — `.claude/commands/depth.md` + +**Files:** +- Create: `.claude/commands/depth.md` +- 참고(형식 일치용): `.claude/commands/branch.md` + +- [ ] **Step 1: 파일 생성 (Write 도구)** + +아래 전체 내용으로 작성: + +````markdown +--- +description: 브랜치 노트가 구현 착수할 만큼 깊은지 read-only 게이트로 판정 +argument-hint: <브랜치 이름> +--- + +브랜치 노트 1개의 **구현 착수 깊이**를 판정합니다. (기준: `rules/branch-depth-gate.md`) + +**브랜치 이름:** $ARGUMENTS + +## 작업 절차 + +1. **인자 검증** + - 인자가 비어 있으면 사용자에게 브랜치 이름 요청. + - `raw/branch-notes/.md` 경로로 해석. `.md` 가 이미 붙어 있거나 `feature-` prefix 가 없어도 관대히 보정해 매칭 시도. + +2. **파일 존재 확인** + - `raw/branch-notes/.md` 가 없으면 경로만 안내하고 종료. (생성하지 않음 — 그건 `/branch` 의 일.) + +3. **감사기 디스패치** + - `branch-depth-auditor` 서브에이전트를 호출하고 입력으로 브랜치 노트 경로를 전달. + - 감사기는 read-only — 어떤 파일도 수정하지 않는다. + +4. **리포트 출력 (인라인)** + - 감사기 리포트(Verdict + Findings 표 + 다음 행동)를 그대로 사용자에게 출력. + - **브랜치 노트에 판정을 쓰지 않는다.** 파일로 남길지는 사용자가 따로 요청할 때만(그 경우 `raw/`·`wiki/`·`docs/` 가 아닌 경로 또는 인라인 유지 — claim-gate hook 충돌 회피). + +5. **루프 안내** + - `Not ready` 면: "위 '채울 방법' 순서로 노트 보강 후 `/depth ` 재실행" 안내. + - `Ready` 면: "구현 착수 가능" 안내. Should-fix 가 남았으면 "감수하고 착수할지" 확인. + +## 규칙 + +- **판정만**. 노트를 자동 보강하지 않는다(접근법 B 는 옵트인 — R1 갭에 한해 `wiki-decision-researcher` 권고만). +- `/depth` 는 멱등(idempotent): 같은 노트에 몇 번 돌려도 안전(read-only). +- `wiki/log.md` 에 기록하지 않음(판정은 빈번, 노이즈). +```` + +- [ ] **Step 2: 구조 검증 (grep)** + +Run: +```bash +cd "/home/donghyeon/Documents/LLM Wiki" && grep -c "argument-hint" .claude/commands/depth.md && grep -c "branch-depth-auditor" .claude/commands/depth.md && grep -c "raw/branch-notes" .claude/commands/depth.md && grep -ci "재실행\|루프" .claude/commands/depth.md +``` +Expected: 네 grep 모두 1+. + +- [ ] **Step 3: 체크포인트** — `/depth` 절차가 스펙 §6 과 일치하는지 확인. + +--- + +## Task 4: 템플릿 캡처 칸 — `templates/branch-note-template.md` + +**Files:** +- Modify: `templates/branch-note-template.md` + +> 기존 80개 브랜치는 미변경. 신규 브랜치부터 R2·R4 를 작성 시점에 캡처. + +- [ ] **Step 1: Decision Evidence Map 에 `선택 조건` 열 추가 (Edit 도구)** + +Old (정확히 이 블록): +```markdown +| Decision ID | Decision | Supporting Claims | Evidence Strength | Open Risk | +|---|---|---|---|---| +| D1 | <결정 내용> | `raw/official-docs/.md#C1`, `raw/company-tech-blogs/.md#C2` | `official-vendor-doc + company-case-study` | <아직 검증해야 할 위험> | +| D2 | <결정 내용> | `raw/official-docs/.md#C3` | `official-standard` | <위험 또는 N/A> | +``` +New: +```markdown +| Decision ID | Decision | 선택 조건 (언제 이 결정 / 언제 대안) | Supporting Claims | Evidence Strength | Open Risk | +|---|---|---|---|---|---| +| D1 | <결정 내용> | <이 조건일 때 이 결정, 다른 조건이면 어떤 대안> | `raw/official-docs/.md#C1`, `raw/company-tech-blogs/.md#C2` | `official-vendor-doc + company-case-study` | <아직 검증해야 할 위험> | +| D2 | <결정 내용> | <선택 조건 또는 N/A — 분기 없으면 N/A> | `raw/official-docs/.md#C3` | `official-standard` | <위험 또는 N/A> | +``` + +- [ ] **Step 2: `## 엣지·실패·의존` 미니 섹션 추가 (Edit 도구)** + +Old (정확히 이 블록 — `## 검증해야 할 주장` 헤더 앞): +```markdown +## 검증해야 할 주장 / Claims To Verify +``` +New: +```markdown +## 엣지·실패·의존 / Edge · Failure · Dependency + +> R4(깊이 게이트) 캡처용. 정상 경로 외에 *구현 중 부딪힐* 실패/엣지/다른 계약 의존을 미리 열거. 없으면 "해당 없음" 명시(공란 금지). + +- **실패·엣지 경로**: <입력 경계 / 타임아웃 / 부분 실패 / 동시성 등 — 각 경로의 기대 동작> +- **다른 계약 의존**: `[[raw/branch-notes/]]` 의 `D` 에 의존 — <무엇을 consume 하는지, 그 계약이 바뀌면 본 브랜치 영향> + +## 검증해야 할 주장 / Claims To Verify +``` + +- [ ] **Step 3: 구조 검증 (grep)** + +Run: +```bash +cd "/home/donghyeon/Documents/LLM Wiki" && grep -c "선택 조건 (언제 이 결정" templates/branch-note-template.md && grep -c "## 엣지·실패·의존" templates/branch-note-template.md && grep -c "## Decision Evidence Map\|## 구현 가이드\|## 검증해야 할 주장" templates/branch-note-template.md +``` +Expected: 첫 둘 1, 셋째 3 (기존 핵심 섹션 보존 확인 — claim-gate 가 요구하는 Decision Evidence Map 유지). + +- [ ] **Step 4: 체크포인트** — 템플릿 흐름이 자연스러운지, 과하지 않은지(YAGNI) 확인. + +--- + +## Task 5: 워크플로우 진입점 등재 — `CLAUDE.md`, `AGENTS.md` + +**Files:** +- Modify: `CLAUDE.md` +- Modify: `AGENTS.md` + +> `/depth` 와 게이트가 워크플로우에서 발견 가능하도록 SSOT 진입점에 1줄씩 추가. 추가만(additive), 기존 규칙 변경 금지. + +- [ ] **Step 1: CLAUDE.md 의 커맨드/파이프라인 목록 위치 확인** + +Run: `cd "/home/donghyeon/Documents/LLM Wiki" && grep -n "/branch\|/ingest\|/lint\|커맨드\|command" CLAUDE.md | head -20` +목적: 커맨드들이 나열된 섹션을 찾는다. + +- [ ] **Step 2: CLAUDE.md 에 `/depth` 1줄 추가 (Edit 도구)** + +Step 1 에서 찾은 커맨드 목록에서 `/branch` 항목 바로 아래에, 그 항목과 같은 서식으로 다음 한 줄을 추가: +``` +- `/depth ` — 브랜치 노트가 구현 착수할 만큼 깊은지 read-only 판정 (기준: `rules/branch-depth-gate.md`). 착수 전 게이트. +``` +(주변 항목의 실제 서식 — 불릿 기호·백틱·줄표 — 에 맞춰 조정. 임의로 다른 섹션을 건드리지 말 것.) + +- [ ] **Step 3: AGENTS.md 에 rules 목록 + 커맨드 반영** + +Run: `cd "/home/donghyeon/Documents/LLM Wiki" && grep -n "rules/\|linking-rules\|naming-conventions\|/branch" AGENTS.md | head -20` +찾은 rules 목록에 `rules/branch-depth-gate.md` 를, 커맨드 목록(있으면)에 `/depth` 를 주변 서식대로 1줄씩 추가. 두 목록 중 존재하는 것에만 추가. + +- [ ] **Step 4: 구조 검증 (grep)** + +Run: +```bash +cd "/home/donghyeon/Documents/LLM Wiki" && grep -c "/depth" CLAUDE.md && grep -c "branch-depth-gate" AGENTS.md +``` +Expected: 둘 다 1+ (AGENTS.md 에 rules 목록이 없었다면 0일 수 있음 — 그 경우 Step 3 판단 기록). + +- [ ] **Step 5: 체크포인트** — 추가가 additive 인지(기존 줄 변경 없음), 서식이 주변과 일치하는지 확인. + +--- + +## Task 6: 픽스처 회귀 — 게이트 보정 + +> 본 plan 의 진짜 "test". 감사기가 직관과 일치하는 판정을 내는지 확인. **cwd 가 LLM Wiki 인 세션에서 실행.** + +**대상 픽스처:** +- **깊은 브랜치 (Ready 근접 기대)**: `feature-boundary-validation-mapping-contract` — 여러 번 다듬어 실제 구현 근거로 쓰인 노트. +- **얕은 브랜치 (Not ready 기대)**: 사용자가 "아직 얕다"고 아는 초기 브랜치 1개 (예: `status_label: in-progress` 이고 `planned` 항목이 많은 것). 후보 탐색: + `cd "/home/donghyeon/Documents/LLM Wiki" && grep -rl "documented-only\|planned" raw/branch-notes/ | head` → 그 중 하나를 사용자와 합의해 선택. + +- [ ] **Step 1: 깊은 브랜치 감사** + +`/depth feature-boundary-validation-mapping-contract` 실행 (또는 `branch-depth-auditor` 직접 디스패치). +Expected: `Ready` 또는 Blocking 0~소수. Blocking 이 다수면 → 룰북 R1~R4 기준이 너무 빡셈 → Task 1 의 Pass 기준 재보정. + +- [ ] **Step 2: 얕은 브랜치 감사** + +선택한 얕은 브랜치에 `/depth ` 실행. +Expected: `Not ready` + R1~R4 에 걸친 finding. Findings 가 비면 → 기준이 너무 느슨 → Task 1 재보정. + +- [ ] **Step 3: finding 품질 점검** + +두 리포트의 각 finding 이 4종 세트(심각도·위치·예상 의구심·채울 방법)를 갖췄는지 육안 확인. 빠진 게 있으면 → Task 2 의 출력 형식/불변식 보강. + +- [ ] **Step 4: 보정 루프** + +Step 1~3 에서 판정 방향이 직관과 어긋나면 Task 1(기준) 또는 Task 2(감사기 프롬프트)를 수정하고 다시 Step 1 부터. 방향이 맞을 때까지. + +- [ ] **Step 5: 체크포인트 (최종)** — 두 픽스처 판정이 직관과 일치 + finding 4종 세트 충족 → P2 완료. 사용자에게 결과 리포트. + +--- + +## Self-Review (작성자 점검 결과) + +- **스펙 커버리지**: §4(4축)→Task1, §4.1(사다리)→Task1, §5(감사기)→Task2, §6(커맨드)→Task3, §7(템플릿)→Task4, §10(검증)→Task6, §12(산출물4개+진입점)→Task1~5. §11(P3)는 의도적으로 별도 사이클(범위 밖, 명시됨). 누락 없음. +- **placeholder**: 각 파일의 전체 내용을 inline 제공(TBD 없음). Task6 얕은 픽스처만 "사용자 합의로 선택" — 이는 calibration test 의 본질(정답이 사용자 판단)이라 의도적. +- **타입/명명 일관성**: `branch-depth-gate.md`/`branch-depth-auditor`/`/depth` 셋 통일. 축 라벨 `R1~R4`(Decision ID `D*` 와 분리). 실패모드 7종이 Task1 정의 ↔ Task2 사용 일치. + +--- + +## Execution Handoff + +P2 구현 plan 완료. 다음 단계는 plan 본문 상단 안내대로 subagent-driven 또는 inline 실행. diff --git a/docs/superpowers/plans/2026-06-02-obsidian-link-validation-hardening.md b/docs/superpowers/plans/2026-06-02-obsidian-link-validation-hardening.md new file mode 100644 index 0000000..f1caaa6 --- /dev/null +++ b/docs/superpowers/plans/2026-06-02-obsidian-link-validation-hardening.md @@ -0,0 +1,426 @@ +# 옵시디언 링크 검증 강화 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** `wiki_structure_lint.py`의 C2 링크 검사를 정확하게 만들어(비-md 첨부 오탐 + backtick 셀경계 오탐 제거 + heading anchor 정확화) zero-tolerance 강제의 신뢰 토대를 세운다. + +**Architecture:** 단일 파일(`.claude/hooks/wiki_structure_lint.py`)의 `build_vault_index`(A1)·`check_c2`(A2/B)·docstring(D)을 수정하고, stdlib `unittest` 테스트 파일을 신설한다. C1/C3는 불변. + +**Tech Stack:** Python 3 stdlib only (re, pathlib, unittest, tempfile). 외부 의존성 0. + +> **환경 비고:** 이 repo는 `.git`이 빈 디렉터리(git 미초기화). **커밋 단계는 생략하고, 각 Task의 체크포인트 = 전체 테스트 스위트 실행 통과**로 대체한다. 명령: `python3 .claude/hooks/test_wiki_structure_lint.py -v`. + +--- + +## File Structure + +- **Modify** `.claude/hooks/wiki_structure_lint.py` + - `build_vault_index` (현재 154-162): 비-md 첨부 인덱싱 (A1) + - `check_c2` (현재 187-226): backtick 위치기반 판정 (A2) + anchor 정확화 (B) + - module docstring (현재 1-20): 지원 문법 계약 표 (D) +- **Create** `.claude/hooks/test_wiki_structure_lint.py` — A1/A2/B 단위 테스트 +- **Modify** `rules/linking-rules.md` — C2 집행기 참조 1줄 (D) + +--- + +## Task 1: 테스트 스캐폴드 + A2 backtick 셀경계 오탐 수정 + +**Files:** +- Create: `.claude/hooks/test_wiki_structure_lint.py` +- Modify: `.claude/hooks/wiki_structure_lint.py` (`check_c2`, 187-226) + +핵심 버그: `check_c2`가 두 패스(① `BACKTICK_LINK.search(line)` 경고 ② `bare`에서 BROKEN 검사)로 나뉘는데, ①의 정규식이 backtick을 좌→우 연속 페어링하지 않아 표의 서로 다른 칸 인라인코드 사이에 낀 정상 위키링크를 오탐. → **위치 기반 단일 패스**로 통합: `INLINE_CODE.finditer(line)`로 code span 범위를 구해, 위키링크 시작이 그 범위 안일 때만 `BACKTICK_WRAPPED_LINK`. + +- [ ] **Step 1: 실패 테스트 작성** — `test_wiki_structure_lint.py` 신설 + +```python +#!/usr/bin/env python3 +"""wiki_structure_lint.py 단위 테스트 (stdlib unittest).""" +import importlib.util +import tempfile +import unittest +from pathlib import Path + +# 하이픈 모듈명이 아니라 언더스코어 — 직접 spec 로드 +_SPEC = importlib.util.spec_from_file_location( + "wsl", str(Path(__file__).with_name("wiki_structure_lint.py"))) +wsl = importlib.util.module_from_spec(_SPEC) +_SPEC.loader.exec_module(wsl) + + +def _doc(*lines): + """check_c2 입력용 최소 doc dict.""" + return {"lines": list(lines)} + + +def _codes(findings): + return [c for (c, _ln, _msg) in findings] + + +class TestBacktickPairing(unittest.TestCase): + def setUp(self): + # 타깃 존재로 BROKEN_LINK 격리 — 'foo'는 vault에 있다고 가정 + self.vp = {"raw/x/foo"} + self.vb = {"foo": ["raw/x/foo"]} + self.root = Path("/nonexistent") + + def test_cross_cell_codespans_not_flagged(self): + # 서로 다른 칸의 인라인코드 사이 정상 위키링크 (짝수 backtick) → 오탐 아님 + line = "| D1 | `AUTH` 응답 | [[foo]] (`note` 보강) | `strength` |" + f = wsl.check_c2(_doc(line), self.vp, self.vb, self.root, {}) + self.assertNotIn("BACKTICK_WRAPPED_LINK", _codes(f)) + + def test_true_wrapped_link_flagged(self): + # 진짜 code span 내부 링크 → 검출 + line = "예시 문법: `[[foo]]` 처럼 씁니다" + f = wsl.check_c2(_doc(line), self.vp, self.vb, self.root, {}) + self.assertIn("BACKTICK_WRAPPED_LINK", _codes(f)) + + +if __name__ == "__main__": + unittest.main(verbosity=2) +``` + +- [ ] **Step 2: 실패 확인** + +Run: `python3 .claude/hooks/test_wiki_structure_lint.py -v` +Expected: `test_cross_cell_codespans_not_flagged` FAIL (현재 오탐으로 BACKTICK_WRAPPED_LINK 발생). `test_true_wrapped_link_flagged` PASS. + +- [ ] **Step 3: `check_c2` 위치기반 단일 패스로 교체** + +`wiki_structure_lint.py`의 `check_c2` 본문(187-226)을 아래로 교체: + +```python +def check_c2(doc, vault_paths, vault_bases, root, cache): + out = [] + in_fence = False + for lineno, line in enumerate(doc["lines"], start=1): + s = line.lstrip() + if s.startswith("```") or s.startswith("~~~"): + in_fence = not in_fence + continue + if in_fence: + continue + # 인라인 code span 범위 (좌→우 연속 페어링; `[^`]*` 가 backtick 못 넘음) + code_spans = [(m.start(), m.end()) for m in INLINE_CODE.finditer(line)] + for m in WIKILINK.finditer(line): + if any(a <= m.start() < b for a, b in code_spans): + out.append(("BACKTICK_WRAPPED_LINK", lineno, + f"백틱/인라인코드에 싸인 위키링크 — 옵시디언 링크 미작동: {line.strip()[:80]}")) + continue + raw = m.group(1).split("|")[0].strip() + target, _, anchor = raw.partition("#") + target, anchor = target.strip(), anchor.strip() + if target.endswith(".md"): # 옵시디언은 [[x.md]] 도 유효 + target = target[:-3] + if not target: + continue + if target not in vault_paths and target not in vault_bases: + out.append(("BROKEN_LINK", lineno, f"타깃 부재: [[{target}]]")) + continue + if anchor: + _check_anchor(out, lineno, target, anchor, + vault_paths, vault_bases, root, cache) + return out +``` + +> 비고: 이 Task에서는 `_check_anchor`를 아직 정의하지 않으므로, **임시로** 기존 anchor 로직을 인라인 유지한다. 아래 Step 3b 참조 (Task 3에서 `_check_anchor`로 추출). + +- [ ] **Step 3b: anchor 로직 임시 인라인** — 위 `_check_anchor(...)` 호출을 Task 3 전까지 기존 substring 로직으로 대체: + +```python + if anchor: + rels = [target] if target in vault_paths else vault_bases.get(target, []) + found = False + for rel in rels: + fp = root / (rel + ".md") + txt = cache.get(fp) + if txt is None: + txt = read_text(fp) + cache[fp] = txt + if anchor.lower() in txt.lower(): + found = True + break + if not found: + out.append(("DANGLING_ANCHOR", lineno, f"앵커 부재: [[{target}#{anchor}]]")) +``` + +(즉 Step 3의 `_check_anchor(...)` 한 줄을 이 블록으로 치환해서 작성. `BACKTICK_LINK`·`bare` 변수는 더 이상 사용 안 함.) + +- [ ] **Step 4: 통과 확인** + +Run: `python3 .claude/hooks/test_wiki_structure_lint.py -v` +Expected: 두 테스트 모두 PASS. + +- [ ] **Step 5: 회귀 — 직전 두 노트의 backtick 오탐 소멸 확인** + +Run: `python3 .claude/hooks/wiki_structure_lint.py --file raw/branch-notes/feature-api-contract-baseline.md --links-only` +Expected: `BACKTICK_WRAPPED_LINK` 라인(122/125/151/183/188/315) 출력에서 사라짐. + +- [ ] **Step 6: 체크포인트** — 전체 테스트 통과 확인 (git 미사용) + +Run: `python3 .claude/hooks/test_wiki_structure_lint.py` +Expected: `OK`. + +--- + +## Task 2: A1 — 비-md 첨부 인덱싱 (`.drawio` 오탐 제거) + +**Files:** +- Modify: `.claude/hooks/wiki_structure_lint.py` (`build_vault_index`, 154-162) +- Modify: `.claude/hooks/test_wiki_structure_lint.py` + +- [ ] **Step 1: 실패 테스트 추가** — `test_wiki_structure_lint.py`에 클래스 추가 + +```python +class TestNonMdAttachment(unittest.TestCase): + def test_drawio_target_resolves(self): + with tempfile.TemporaryDirectory() as d: + root = Path(d) + (root / "raw" / "diagrams").mkdir(parents=True) + (root / "raw" / "diagrams" / "arch.drawio").write_text("") + (root / "raw" / "notes").mkdir(parents=True) + note = root / "raw" / "notes" / "n.md" + note.write_text("see [[raw/diagrams/arch.drawio]]\n") + vp, vb = wsl.build_vault_index(root) + f = wsl.check_c2(_doc("see [[raw/diagrams/arch.drawio]]"), + vp, vb, root, {}) + self.assertNotIn("BROKEN_LINK", _codes(f)) + + def test_missing_drawio_still_broken(self): + with tempfile.TemporaryDirectory() as d: + root = Path(d) + (root / "raw").mkdir() + vp, vb = wsl.build_vault_index(root) + f = wsl.check_c2(_doc("see [[raw/diagrams/ghost.drawio]]"), + vp, vb, root, {}) + self.assertIn("BROKEN_LINK", _codes(f)) + + def test_git_dir_excluded(self): + with tempfile.TemporaryDirectory() as d: + root = Path(d) + (root / ".git").mkdir() + (root / ".git" / "obj.drawio").write_text("x") + vp, vb = wsl.build_vault_index(root) + self.assertNotIn(".git/obj.drawio", vp) +``` + +- [ ] **Step 2: 실패 확인** + +Run: `python3 .claude/hooks/test_wiki_structure_lint.py -v` +Expected: `test_drawio_target_resolves` FAIL (BROKEN_LINK 발생 — 비-md 미인덱싱). + +- [ ] **Step 3: `build_vault_index` 교체** + +```python +def build_vault_index(root): + """링크 타깃 확인용. md는 .md strip, 비-md 첨부는 확장자 포함으로 등록. + 숨김 디렉터리(.git 등)는 제외. (paths, bases=basename→rel목록).""" + paths, bases = set(), {} + for p in root.rglob("*"): + if not p.is_file(): + continue + rel_posix = p.relative_to(root).as_posix() + if rel_posix.startswith(".") or "/." in rel_posix: + continue # .git / .obsidian 등 숨김 경로 제외 + if p.suffix == ".md": + rel = rel_posix[:-3] + paths.add(rel) + bases.setdefault(p.stem, []).append(rel) + else: + paths.add(rel_posix) # 확장자 포함 full path + bases.setdefault(p.name, []).append(rel_posix) # 확장자 포함 basename + return paths, bases +``` + +- [ ] **Step 4: 통과 확인** + +Run: `python3 .claude/hooks/test_wiki_structure_lint.py -v` +Expected: 3개 신규 테스트 + Task 1 테스트 모두 PASS. + +- [ ] **Step 5: 회귀 — vault에서 .drawio 오탐 소멸** + +Run: `python3 .claude/hooks/wiki_structure_lint.py --all --links-only 2>&1 | grep -c 'drawio'` +Expected: `0` (이전엔 8). + +- [ ] **Step 6: 체크포인트** + +Run: `python3 .claude/hooks/test_wiki_structure_lint.py` +Expected: `OK`. + +--- + +## Task 3: B — heading anchor 정확화 (substring → 실제 heading 매칭) + +**Files:** +- Modify: `.claude/hooks/wiki_structure_lint.py` (`check_c2` anchor 블록 → `_check_anchor` 추출 + 헬퍼) +- Modify: `.claude/hooks/test_wiki_structure_lint.py` + +- [ ] **Step 1: 실패 테스트 추가** + +```python +class TestHeadingAnchor(unittest.TestCase): + def _vault(self, d): + root = Path(d) + (root / "wiki").mkdir() + tgt = root / "wiki" / "t.md" + tgt.write_text("# Title\n\n## Real Heading\n\nbody real heading mention\n") + return root + + def test_existing_heading_passes(self): + with tempfile.TemporaryDirectory() as d: + root = self._vault(d) + vp, vb = wsl.build_vault_index(root) + f = wsl.check_c2(_doc("[[wiki/t#Real Heading]]"), vp, vb, root, {}) + self.assertNotIn("DANGLING_ANCHOR", _codes(f)) + + def test_substring_only_match_now_dangling(self): + # 'body'는 본문에만 있고 heading 아님 → 강화 후 DANGLING + with tempfile.TemporaryDirectory() as d: + root = self._vault(d) + vp, vb = wsl.build_vault_index(root) + f = wsl.check_c2(_doc("[[wiki/t#body]]"), vp, vb, root, {}) + self.assertIn("DANGLING_ANCHOR", _codes(f)) + + def test_nonmd_anchor_skipped(self): + # 비-md 타깃 + anchor → anchor 검사 skip (DANGLING 아님) + with tempfile.TemporaryDirectory() as d: + root = Path(d) + (root / "raw").mkdir() + (root / "raw" / "a.drawio").write_text("") + vp, vb = wsl.build_vault_index(root) + f = wsl.check_c2(_doc("[[raw/a.drawio#x]]"), vp, vb, root, {}) + self.assertNotIn("DANGLING_ANCHOR", _codes(f)) +``` + +- [ ] **Step 2: 실패 확인** + +Run: `python3 .claude/hooks/test_wiki_structure_lint.py -v` +Expected: `test_substring_only_match_now_dangling` FAIL (현재 substring으로 'body' 통과). + +- [ ] **Step 3: 헬퍼 + `_check_anchor` 추가, anchor 블록 교체** + +`check_c2` 위에 헬퍼 추가: + +```python +HEADING_RE = re.compile(r"^#{1,6}\s+(.+?)\s*$", re.M) + + +def _heading_set(txt): + return {h.strip().lower() for h in HEADING_RE.findall(txt)} + + +def _check_anchor(out, lineno, target, anchor, vault_paths, vault_bases, root, cache): + rels = [target] if target in vault_paths else vault_bases.get(target, []) + md_rels = [r for r in rels if (root / (r + ".md")).exists()] + if not md_rels: + return # 비-md 첨부 등 — anchor 검사 무의미, skip + is_block = anchor.startswith("^") + norm = anchor[1:].strip() if is_block else anchor.strip().lower() + for rel in md_rels: + fp = root / (rel + ".md") + txt = cache.get(fp) + if txt is None: + txt = read_text(fp) + cache[fp] = txt + if is_block: + if re.search(r"\^" + re.escape(norm) + r"\s*$", txt, re.M): + return + else: + if norm in _heading_set(txt): + return + out.append(("DANGLING_ANCHOR", lineno, f"앵커 부재: [[{target}#{anchor}]]")) +``` + +그리고 `check_c2`의 anchor 블록(Task 1 Step 3b에서 인라인한 부분)을 한 줄로 교체: + +```python + if anchor: + _check_anchor(out, lineno, target, anchor, + vault_paths, vault_bases, root, cache) +``` + +- [ ] **Step 4: 통과 확인** + +Run: `python3 .claude/hooks/test_wiki_structure_lint.py -v` +Expected: 전체 테스트 PASS. + +- [ ] **Step 5: 회귀 — vault DANGLING_ANCHOR 수치 확인** + +Run: `python3 .claude/hooks/wiki_structure_lint.py --all --links-only 2>&1 | grep -c DANGLING_ANCHOR` +Expected: 정수 출력(이전 3건 대비 변동 가능 — 강화로 증가할 수 있음, 정상). + +- [ ] **Step 6: 체크포인트** + +Run: `python3 .claude/hooks/test_wiki_structure_lint.py` +Expected: `OK`. + +--- + +## Task 4: D — 문법 계약 문서화 (docstring + linking-rules 참조) + +**Files:** +- Modify: `.claude/hooks/wiki_structure_lint.py` (module docstring, 1-20) +- Modify: `rules/linking-rules.md` + +- [ ] **Step 1: docstring의 C2 설명 교체** + +`wiki_structure_lint.py` 상단 docstring에서 ` C2 옵시디언 링크 문법 — 백틱 래핑 / 깨진 타깃 / 부재 앵커` 줄을 아래로 확장: + +``` + C2 옵시디언 링크 문법 — 지원 형태 + 위반 정의: + [[t]] / [[t.md]] / [[t|alias]] → t 실존 검사 (md=확장자strip, 첨부=확장자포함) + ![[t]] → embed, 동일 타깃 검사 + [[t#heading]] → t의 실제 heading 매칭 (DANGLING_ANCHOR) + [[t#^blockid]] → t의 ^blockid 행말 토큰 (DANGLING_ANCHOR) + `[[t]]` (인라인 code span 내부) → BACKTICK_WRAPPED_LINK (옵시디언 링크 미렌더) + ``` fenced ``` 내부 [[t]] → 예시로 간주, 스킵 + 판정은 위치기반 backtick 연속 페어링 — 표 셀 경계 오탐 없음. +``` + +- [ ] **Step 2: docstring 유효성 확인 (구문 깨짐 없음)** + +Run: `python3 -c "import importlib.util,pathlib; s=importlib.util.spec_from_file_location('w','.claude/hooks/wiki_structure_lint.py'); m=importlib.util.module_from_spec(s); s.loader.exec_module(m); print('ok')"` +Expected: `ok`. + +- [ ] **Step 3: `rules/linking-rules.md`에 집행기 참조 1줄 추가** + +`rules/linking-rules.md`의 검증 체크리스트 관련 섹션 끝에 추가 (적절한 위치에 1줄): + +```markdown +> **결정론 집행기**: 위 옵시디언 링크 문법(broken target / dangling anchor / backtick 래핑)은 `.claude/hooks/wiki_structure_lint.py`의 C2 검사가 기계적으로 강제한다 (`--all --links-only`로 vault 전수, zero-tolerance). +``` + +- [ ] **Step 4: 체크포인트** + +Run: `python3 .claude/hooks/test_wiki_structure_lint.py && python3 .claude/hooks/wiki_structure_lint.py --file raw/branch-notes/feature-api-contract-baseline.md --links-only` +Expected: 테스트 `OK` + 파일 검사 정상 출력. + +--- + +## Task 5: 롤아웃 — 정확한 깨진 링크 목록 산출 + +**Files:** 없음 (측정만) + +- [ ] **Step 1: vault 전수 재실행** + +Run: `python3 .claude/hooks/wiki_structure_lint.py --all --links-only 2>&1 | tail -15` +Expected: 요약에서 `BACKTICK_WRAPPED_LINK` 대폭 감소(오탐 제거), `BROKEN_LINK`는 .drawio 8건 제거 후 *진짜* 회색 노드만 남음. + +- [ ] **Step 2: 진짜 BROKEN_LINK 타깃 빈도표 산출** + +Run: `python3 .claude/hooks/wiki_structure_lint.py --all --links-only 2>&1 | grep BROKEN_LINK | sed -E 's/.*\[\[([^]]*)\]\].*/\1/' | sort | uniq -c | sort -rn` +Expected: 미생성 daily-note(`raw/daily-notes/2026-05-25` 등) + 미작성 concept 목록. 이 목록이 후속 정리(스텁/링크수정)의 입력. + +- [ ] **Step 3: 사용자에게 정리 목록 보고** + +산출된 진짜 깨진 링크 목록을 사용자에게 제시하고, 정리(스텁 생성 vs 링크 제거)는 별도 작업으로 진행 여부 확인. (본 plan 범위는 린터까지.) + +--- + +## Self-Review (작성자 점검 완료) + +- **Spec coverage:** A1(Task2)·A2(Task1)·B(Task3)·C(Task5 강제 측정)·D(Task4) 전부 task 존재. ✓ +- **Placeholder scan:** 모든 code step에 실제 코드 포함. "TBD"/"적절히" 없음. ✓ +- **Type consistency:** `_check_anchor`/`_heading_set`/`HEADING_RE` Task3에서 정의 후 Task1 호출부와 시그니처 일치. Task1 Step3b가 임시 인라인 → Task3가 추출로 대체(순서 명시). `build_vault_index` 반환 `(paths, bases)` 불변. ✓ +- **환경:** git 미초기화 → 커밋 대신 테스트 체크포인트(헤더 명시). ✓ diff --git a/docs/superpowers/plans/2026-06-04-three-platform-sync-phase0-engine-agents.md b/docs/superpowers/plans/2026-06-04-three-platform-sync-phase0-engine-agents.md new file mode 100644 index 0000000..ffd4d97 --- /dev/null +++ b/docs/superpowers/plans/2026-06-04-three-platform-sync-phase0-engine-agents.md @@ -0,0 +1,809 @@ +# 3-플랫폼 동기화 Phase 0 — 생성 엔진 + agents Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Claude의 9개 agent를 Codex CLI(`.codex/agents/*.toml`)와 Antigravity CLI(`.agents/agents//agent.json`)의 native 포맷으로 생성하는 멱등 스크립트 `scripts/sync-automation.py`를 만들고, 누락된 2개 agent(`branch-depth-auditor`·`coverage-auditor`)를 양 플랫폼에 추가한다. + +**Architecture:** Claude `.claude/agents/.md` frontmatter의 `tools:`를 **권한 SSOT**로 삼아 codex `sandbox_mode`와 antigravity `toolNames`를 기계적으로 파생한다. 프롬프트 본문은 플랫폼별 SSOT(`.codex/agents/.md` = codex 일반화 본문, `.agents/plugins/wiki-superpowers/agents/.md` = antigravity gated 본문)에서 가져와 native 머신 포맷으로 포장한다. 스크립트는 순수 함수(권한 파생·포맷 직렬화)와 I/O를 분리하고, `--check` 모드로 SSOT↔생성물 drift를 0으로 검증한다. + +**Tech Stack:** Python 3.12 (stdlib only — `tomllib` for TOML 검증, `json`, `pathlib`, `argparse`), pytest. + +--- + +## 배경 / 현재 상태 (실측) + +- Claude agents (SSOT identity + 권한): `.claude/agents/*.md` — frontmatter `name`/`description`/`tools`(콤마 목록)/`model: sonnet`. 9개 존재. +- Codex agents: `.codex/agents/*.md` — frontmatter `name`/`description`(tools/model 없음) + 일반화 본문. **7개** (branch-depth-auditor·coverage-auditor 누락). codex가 실제 읽는 native 포맷은 `*.toml`인데 **하나도 없음**. +- Antigravity agents: `.agents/plugins/wiki-superpowers/agents/*.md` — frontmatter `name`/`description` + G1~G4 gate 본문. **7개** (동일 2개 누락). antigravity가 실제 읽는 `.agents/agents//agent.json` **하나도 없음** (디스크의 `~/.gemini/.../agent.json`은 stale·오류 생성물 — read-only agent에 write 도구가 들어있고 content가 요약됨. 신뢰 금지). + +**확정된 agent.json 스키마** (실 디스크 `~/.gemini/antigravity-cli/brain/.../wiki-research-lane/agent.json`에서 키 구조만 채택): +```json +{ + "name": "", + "description": "", + "hidden": true, + "config": { + "customAgent": { + "systemPromptSections": [ { "title": "Agent System Instructions", "content": "" } ], + "toolNames": [ ... ], + "systemPromptConfig": { + "includeSections": ["user_information","mcp_servers","skills","subagent_reminder","messaging","artifacts","user_rules"] + } + } + } +} +``` + +**권한 파생 규칙** (Claude `tools:` → 플랫폼): + +| Claude tool | Antigravity `toolNames` | 비고 | +|---|---|---| +| (모든 agent 공통 baseline) | `send_message`, `view_file`, `find_by_name`, `grep_search`, `list_dir` | 9개 모두 Read+Grep+Glob 보유 | +| `Bash` | `run_command` | | +| `Edit` | `replace_file_content`, `multi_replace_file_content` | | +| `Write` | `write_to_file` | | +| `WebFetch` | `read_url_content` | | +| `WebSearch` | `search_web` | | + +- Codex `sandbox_mode` = `workspace-write` (Claude tools에 `Edit` 또는 `Write` 포함 시) / else `read-only`. +- 9개 agent 권한 (Claude frontmatter 실측): + - read-only: `branch-depth-auditor`(Read,Grep,Glob), `coverage-auditor`·`wiki-adversarial-reviewer`·`wiki-diagram-reviewer`·`wiki-link-verifier`·`wiki-research-lane`(Read,Grep,Glob,Bash) + - workspace-write: `wiki-doc-author`(+Edit,Write), `wiki-source-summarizer`(+Edit,Write,WebFetch), `wiki-decision-researcher`(+Write,WebSearch,WebFetch) + +--- + +## File Structure + +- Create: `scripts/sync-automation.py` — 단일 진입점 CLI. 순수 함수 구역(파싱·권한 파생·직렬화) + I/O 구역(파일 read/write) + `argparse` CLI. +- Create: `scripts/test_sync_automation.py` — pytest 단위 테스트 (순수 함수 + 생성물 유효성). +- Create: `.codex/agents/branch-depth-auditor.md`, `.codex/agents/coverage-auditor.md` — codex 일반화 본문 SSOT (Claude에서 적응). +- Create: `.agents/plugins/wiki-superpowers/agents/branch-depth-auditor.md`, `.agents/plugins/wiki-superpowers/agents/coverage-auditor.md` — antigravity gated 본문 SSOT. +- Generate (스크립트 출력): `.codex/agents/.toml` ×9, `.agents/agents//agent.json` ×9. +- Modify (Phase 0 말미, 최소): `.codex/agents/README.md`, `.agents/plugins/wiki-superpowers/README.md` — 생성 스크립트 사용법 1단락. (전체 문서 정리는 Phase 2.) + +> 책임 경계: `sync-automation.py`는 *권한 파생 + 포맷 포장*만 한다. 본문 프로즈의 플랫폼 적응(일반화·gate 작성)은 사람이 SSOT `.md`에 직접 한다. codex는 `.toml`만 로드하므로 `.codex/agents/*.md`는 우리 SSOT로 남고 codex는 무시한다. + +--- + +## Task 1: 스크립트 골격 + frontmatter 파싱 + 권한 파생 (순수 함수) + +**Files:** +- Create: `scripts/sync-automation.py` +- Test: `scripts/test_sync_automation.py` + +- [ ] **Step 1: Write the failing test** + +```python +# scripts/test_sync_automation.py +import json +import tomllib + +import sync_automation as s + + +def test_parse_frontmatter_extracts_fields(): + md = ( + "---\n" + "name: wiki-link-verifier\n" + "description: Audit the wiki for orphans.\n" + "tools: Read, Grep, Glob, Bash\n" + "model: sonnet\n" + "---\n\n" + "You are the Wiki Link Verifier.\n" + ) + fm, body = s.parse_frontmatter(md) + assert fm["name"] == "wiki-link-verifier" + assert fm["description"] == "Audit the wiki for orphans." + assert fm["tools"] == "Read, Grep, Glob, Bash" + assert body == "You are the Wiki Link Verifier.\n" + + +def test_parse_tools_list(): + assert s.parse_tools("Read, Grep, Glob, Bash") == ["Read", "Grep", "Glob", "Bash"] + assert s.parse_tools("Read,Edit,Write") == ["Read", "Edit", "Write"] + + +def test_sandbox_mode_read_only_when_no_write_tools(): + assert s.codex_sandbox_mode(["Read", "Grep", "Glob", "Bash"]) == "read-only" + + +def test_sandbox_mode_workspace_write_when_edit_or_write(): + assert s.codex_sandbox_mode(["Read", "Edit", "Write", "Bash"]) == "workspace-write" + assert s.codex_sandbox_mode(["Read", "Write", "WebSearch"]) == "workspace-write" + + +def test_antigravity_toolnames_read_only_agent(): + # Read,Grep,Glob,Bash -> baseline + run_command, no write tools + assert s.antigravity_tool_names(["Read", "Grep", "Glob", "Bash"]) == [ + "send_message", "view_file", "find_by_name", "grep_search", "list_dir", + "run_command", + ] + + +def test_antigravity_toolnames_write_agent_with_web(): + # source-summarizer: Read,Edit,Write,Bash,Grep,Glob,WebFetch + assert s.antigravity_tool_names( + ["Read", "Edit", "Write", "Bash", "Grep", "Glob", "WebFetch"] + ) == [ + "send_message", "view_file", "find_by_name", "grep_search", "list_dir", + "write_to_file", "replace_file_content", "multi_replace_file_content", + "run_command", "read_url_content", + ] +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd scripts && python3 -m pytest test_sync_automation.py -v` +Expected: FAIL with `ModuleNotFoundError: No module named 'sync_automation'`. + +> 참고: 파일명이 `sync-automation.py`(하이픈)라 `import sync_automation`이 안 된다. 테스트 상단에서 모듈을 로드하도록 `conftest.py`로 별칭을 만든다(아래 Step 3에 포함). 또는 파일명을 `sync_automation.py`로 하고 CLI는 `python3 scripts/sync_automation.py`로 부른다. **결정: 파일명을 `scripts/sync_automation.py`(언더스코어)로 한다** — import 가능 + CLI 호출에 지장 없음. 본 계획의 이후 모든 경로에서 `sync_automation.py`로 읽는다. + +- [ ] **Step 3: Write minimal implementation** + +```python +# scripts/sync_automation.py +"""Generate Codex/Antigravity native agent files from Claude SSOT. + +Permission SSOT : .claude/agents/.md frontmatter `tools:` +Codex body SSOT : .codex/agents/.md +Antigravity SSOT : .agents/plugins/wiki-superpowers/agents/.md +Outputs : .codex/agents/.toml , .agents/agents//agent.json +""" +from __future__ import annotations + +import argparse +import json +import sys +from pathlib import Path + +REPO = Path(__file__).resolve().parent.parent + +CLAUDE_AGENTS = REPO / ".claude" / "agents" +CODEX_AGENTS = REPO / ".codex" / "agents" +ANTIGRAV_SSOT = REPO / ".agents" / "plugins" / "wiki-superpowers" / "agents" +ANTIGRAV_OUT = REPO / ".agents" / "agents" + +AGENT_NAMES = [ + "branch-depth-auditor", + "coverage-auditor", + "wiki-adversarial-reviewer", + "wiki-decision-researcher", + "wiki-diagram-reviewer", + "wiki-doc-author", + "wiki-link-verifier", + "wiki-research-lane", + "wiki-source-summarizer", +] + +ANTIGRAV_INCLUDE_SECTIONS = [ + "user_information", "mcp_servers", "skills", + "subagent_reminder", "messaging", "artifacts", "user_rules", +] + +_ANTIGRAV_BASELINE = ["send_message", "view_file", "find_by_name", "grep_search", "list_dir"] +_ANTIGRAV_EXTRA_ORDER = [ + ("Write", ["write_to_file"]), + ("Edit", ["replace_file_content", "multi_replace_file_content"]), + ("Bash", ["run_command"]), + ("WebFetch", ["read_url_content"]), + ("WebSearch", ["search_web"]), +] + + +def parse_frontmatter(md: str) -> tuple[dict[str, str], str]: + lines = md.splitlines(keepends=True) + if not lines or lines[0].strip() != "---": + raise ValueError("missing frontmatter open") + fm: dict[str, str] = {} + i = 1 + while i < len(lines) and lines[i].strip() != "---": + line = lines[i].rstrip("\n") + if ":" in line: + key, _, val = line.partition(":") + fm[key.strip()] = val.strip() + i += 1 + if i >= len(lines): + raise ValueError("missing frontmatter close") + body = "".join(lines[i + 1:]).lstrip("\n") + return fm, body + + +def parse_tools(tools_csv: str) -> list[str]: + return [t.strip() for t in tools_csv.split(",") if t.strip()] + + +def codex_sandbox_mode(tools: list[str]) -> str: + return "workspace-write" if ({"Edit", "Write"} & set(tools)) else "read-only" + + +def antigravity_tool_names(tools: list[str]) -> list[str]: + names = list(_ANTIGRAV_BASELINE) + tset = set(tools) + for claude_tool, mapped in _ANTIGRAV_EXTRA_ORDER: + if claude_tool in tset: + names.extend(mapped) + return names +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `cd scripts && python3 -m pytest test_sync_automation.py -v` +Expected: PASS (6 tests). + +- [ ] **Step 5: Commit** + +```bash +git add scripts/sync_automation.py scripts/test_sync_automation.py +git commit -m "feat(sync): frontmatter parse + permission derivation pure functions" +``` + +--- + +## Task 2: Codex TOML 직렬화 + +**Files:** +- Modify: `scripts/sync_automation.py` +- Test: `scripts/test_sync_automation.py` + +- [ ] **Step 1: Write the failing test** + +```python +def test_codex_toml_is_valid_and_roundtrips(): + body = "You are the Wiki Link Verifier.\nLine two with `backticks` and 'quotes'.\n" + out = s.render_codex_toml( + name="wiki-link-verifier", + description='Audit "the wiki" for orphans.', + sandbox_mode="read-only", + body=body, + ) + parsed = tomllib.loads(out) + assert parsed["name"] == "wiki-link-verifier" + assert parsed["description"] == 'Audit "the wiki" for orphans.' + assert parsed["sandbox_mode"] == "read-only" + assert parsed["developer_instructions"].strip() == body.strip() + + +def test_codex_toml_rejects_triple_single_quote_body(): + import pytest + with pytest.raises(ValueError): + s.render_codex_toml("n", "d", "read-only", "bad ''' body") +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd scripts && python3 -m pytest test_sync_automation.py -k codex_toml -v` +Expected: FAIL with `AttributeError: module 'sync_automation' has no attribute 'render_codex_toml'`. + +- [ ] **Step 3: Write minimal implementation** + +```python +def _toml_basic_string(value: str) -> str: + escaped = value.replace("\\", "\\\\").replace('"', '\\"') + return f'"{escaped}"' + + +def render_codex_toml(name: str, description: str, sandbox_mode: str, body: str) -> str: + if "'''" in body: + raise ValueError("body contains ''' which breaks TOML literal multiline string") + return ( + f"name = {_toml_basic_string(name)}\n" + f"description = {_toml_basic_string(description)}\n" + f"sandbox_mode = {_toml_basic_string(sandbox_mode)}\n" + f"developer_instructions = '''\n" + f"{body.rstrip()}\n" + f"'''\n" + ) +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `cd scripts && python3 -m pytest test_sync_automation.py -k codex_toml -v` +Expected: PASS (2 tests). + +- [ ] **Step 5: Commit** + +```bash +git add scripts/sync_automation.py scripts/test_sync_automation.py +git commit -m "feat(sync): codex TOML serialization with literal multiline body" +``` + +--- + +## Task 3: Antigravity agent.json 직렬화 + +**Files:** +- Modify: `scripts/sync_automation.py` +- Test: `scripts/test_sync_automation.py` + +- [ ] **Step 1: Write the failing test** + +```python +def test_antigravity_agent_json_schema(): + obj = s.build_antigravity_agent( + name="wiki-link-verifier", + description="Audit the wiki.", + body="You are the Wiki Link Verifier.\n", + tools=["Read", "Grep", "Glob", "Bash"], + ) + assert obj["name"] == "wiki-link-verifier" + assert obj["description"] == "Audit the wiki." + assert obj["hidden"] is True + ca = obj["config"]["customAgent"] + assert ca["systemPromptSections"][0]["title"] == "Agent System Instructions" + assert ca["systemPromptSections"][0]["content"] == "You are the Wiki Link Verifier.\n" + assert "write_to_file" not in ca["toolNames"] # read-only agent + assert ca["toolNames"][0] == "send_message" + assert ca["systemPromptConfig"]["includeSections"] == s.ANTIGRAV_INCLUDE_SECTIONS + + +def test_antigravity_json_render_is_valid_json(): + obj = s.build_antigravity_agent("n", "d", "body\n", ["Read", "Grep", "Glob"]) + text = s.render_json(obj) + assert json.loads(text) == obj + assert text.endswith("\n") +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd scripts && python3 -m pytest test_sync_automation.py -k antigravity_agent_json -v` +Expected: FAIL with `AttributeError: ... 'build_antigravity_agent'`. + +- [ ] **Step 3: Write minimal implementation** + +```python +def build_antigravity_agent(name: str, description: str, body: str, tools: list[str]) -> dict: + return { + "name": name, + "description": description, + "hidden": True, + "config": { + "customAgent": { + "systemPromptSections": [ + {"title": "Agent System Instructions", "content": body} + ], + "toolNames": antigravity_tool_names(tools), + "systemPromptConfig": {"includeSections": list(ANTIGRAV_INCLUDE_SECTIONS)}, + } + }, + } + + +def render_json(obj: dict) -> str: + return json.dumps(obj, indent=2, ensure_ascii=False) + "\n" +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `cd scripts && python3 -m pytest test_sync_automation.py -k antigravity_agent_json -v` +Expected: PASS (2 tests). + +- [ ] **Step 5: Commit** + +```bash +git add scripts/sync_automation.py scripts/test_sync_automation.py +git commit -m "feat(sync): antigravity agent.json builder + stable JSON render" +``` + +--- + +## Task 4: CLI 배선 (generate / check) + 기존 7개 검증 + +**Files:** +- Modify: `scripts/sync_automation.py` +- Test: `scripts/test_sync_automation.py` + +- [ ] **Step 1: Write the failing test** + +```python +def test_load_agent_inputs_for_existing_agent(): + inp = s.load_agent_inputs("wiki-link-verifier") + assert inp.tools == ["Read", "Grep", "Glob", "Bash"] + assert inp.codex_description + assert inp.antigrav_description + assert "Wiki Link Verifier" in inp.codex_body + assert inp.antigrav_body + + +def test_generate_one_writes_both_outputs(tmp_path, monkeypatch): + monkeypatch.setattr(s, "CODEX_AGENTS", tmp_path / "codex") + monkeypatch.setattr(s, "ANTIGRAV_OUT", tmp_path / "antigrav") + (tmp_path / "codex").mkdir() + s.generate_one("wiki-link-verifier", check=False) + toml_path = tmp_path / "codex" / "wiki-link-verifier.toml" + json_path = tmp_path / "antigrav" / "wiki-link-verifier" / "agent.json" + assert toml_path.exists() + assert json_path.exists() + assert tomllib.loads(toml_path.read_text())["sandbox_mode"] == "read-only" + assert json.loads(json_path.read_text())["hidden"] is True +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd scripts && python3 -m pytest test_sync_automation.py -k "load_agent_inputs or generate_one" -v` +Expected: FAIL with `AttributeError: ... 'load_agent_inputs'`. + +- [ ] **Step 3: Write minimal implementation** + +```python +from dataclasses import dataclass + + +@dataclass +class AgentInputs: + name: str + tools: list[str] + codex_description: str + codex_body: str + antigrav_description: str + antigrav_body: str + + +def load_agent_inputs(name: str) -> AgentInputs: + claude_fm, _ = parse_frontmatter((CLAUDE_AGENTS / f"{name}.md").read_text()) + codex_fm, codex_body = parse_frontmatter((CODEX_AGENTS / f"{name}.md").read_text()) + ag_fm, ag_body = parse_frontmatter((ANTIGRAV_SSOT / f"{name}.md").read_text()) + return AgentInputs( + name=name, + tools=parse_tools(claude_fm["tools"]), + codex_description=codex_fm["description"], + codex_body=codex_body, + antigrav_description=ag_fm["description"], + antigrav_body=ag_body, + ) + + +def _write_or_check(path: Path, content: str, check: bool, drift: list[str]) -> None: + if check: + current = path.read_text() if path.exists() else None + if current != content: + drift.append(str(path.relative_to(REPO))) + else: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content) + + +def generate_one(name: str, check: bool, drift: list[str] | None = None) -> None: + drift = drift if drift is not None else [] + inp = load_agent_inputs(name) + toml_text = render_codex_toml( + inp.name, inp.codex_description, codex_sandbox_mode(inp.tools), inp.codex_body + ) + json_text = render_json( + build_antigravity_agent(inp.name, inp.antigrav_description, inp.antigrav_body, inp.tools) + ) + _write_or_check(CODEX_AGENTS / f"{name}.toml", toml_text, check, drift) + _write_or_check(ANTIGRAV_OUT / name / "agent.json", json_text, check, drift) + + +def main(argv: list[str] | None = None) -> int: + ap = argparse.ArgumentParser(description="Sync Claude agents -> Codex/Antigravity native files") + ap.add_argument("target", choices=["agents"], help="what to sync") + ap.add_argument("--check", action="store_true", help="fail (exit 2) if outputs drift from SSOT") + ap.add_argument("--only", help="single agent name (default: all)") + args = ap.parse_args(argv) + + names = [args.only] if args.only else AGENT_NAMES + drift: list[str] = [] + for name in names: + generate_one(name, check=args.check, drift=drift) + if args.check and drift: + print("DRIFT detected in:\n " + "\n ".join(drift), file=sys.stderr) + return 2 + action = "checked" if args.check else "generated" + print(f"{action} {len(names)} agents (codex .toml + antigravity agent.json)") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) +``` + +- [ ] **Step 4: Run unit tests (still only 7 agents exist, so use --only)** + +Run: `cd scripts && python3 -m pytest test_sync_automation.py -v` +Expected: PASS (all tests). `load_agent_inputs`/`generate_one` use `wiki-link-verifier` which exists. + +- [ ] **Step 5: Smoke-run on one existing agent** + +Run: +```bash +cd /home/donghyeon/dev/llm-wiki-private +python3 scripts/sync_automation.py agents --only wiki-link-verifier +python3 -c "import tomllib,pathlib; print(tomllib.loads(pathlib.Path('.codex/agents/wiki-link-verifier.toml').read_text())['sandbox_mode'])" +python3 -c "import json,pathlib; o=json.loads(pathlib.Path('.agents/agents/wiki-link-verifier/agent.json').read_text()); print(o['hidden'], 'write_to_file' in o['config']['customAgent']['toolNames'])" +``` +Expected output: +``` +generated 1 agents (codex .toml + antigravity agent.json) +read-only +True False +``` +(`True False` = hidden true + write_to_file absent for read-only agent — confirms the stale-disk bug is fixed.) + +- [ ] **Step 6: Commit** + +```bash +git add scripts/sync_automation.py scripts/test_sync_automation.py .codex/agents/wiki-link-verifier.toml .agents/agents/wiki-link-verifier/agent.json +git commit -m "feat(sync): CLI generate/check + AgentInputs loader; verify on link-verifier" +``` + +--- + +## Task 5: 누락 agent 2개의 codex SSOT 본문 작성 (`branch-depth-auditor`, `coverage-auditor`) + +> codex 본문 = Claude 본문의 일반화: frontmatter에서 `tools:`/`model:` 제거(name+description만 유지), 본문의 `Read tool`/`Edit tool`/`Write tool`/`Bash tool` → `Read`/`Edit`/`Write`/`shell`, `CLAUDE.md` 단독 언급 → `CLAUDE.md (또는 AGENTS.md)`. + +**Files:** +- Create: `.codex/agents/branch-depth-auditor.md` +- Create: `.codex/agents/coverage-auditor.md` + +- [ ] **Step 1: Learn the generalization convention** + +Read these two pairs side by side to learn the exact convention: +- `.claude/agents/wiki-link-verifier.md` vs `.codex/agents/wiki-link-verifier.md` +- Then Read `.claude/agents/branch-depth-auditor.md` and `.claude/agents/coverage-auditor.md` in full. + +- [ ] **Step 2: Create `.codex/agents/branch-depth-auditor.md`** + +Structure: +```markdown +--- +name: branch-depth-auditor +description: +--- + +"Read", "Grep tool"->"Grep", "Glob tool"->"Glob", "Bash tool"->"shell", + "Edit tool"->"Edit", "Write tool"->"Write"; + standalone "CLAUDE.md" reference -> "CLAUDE.md (또는 AGENTS.md)". + Leave all rules/ and templates/ references, axes, and depth-ladder logic byte-identical.> +``` + +- [ ] **Step 3: Create `.codex/agents/coverage-auditor.md`** identically (verbatim description + generalized body). + +- [ ] **Step 4: Verify frontmatter parses for both** + +Run: +```bash +cd /home/donghyeon/dev/llm-wiki-private/scripts && python3 -c " +import sync_automation as s +for n in ['branch-depth-auditor','coverage-auditor']: + fm,body=s.parse_frontmatter(open(f'../.codex/agents/{n}.md').read()) + assert fm['name']==n and fm['description'] and body.strip(), n + assert 'tool' not in fm and 'model' not in fm, 'frontmatter must be name+description only' + print('ok', n) +" +``` +Expected: +``` +ok branch-depth-auditor +ok coverage-auditor +``` + +- [ ] **Step 5: Commit** + +```bash +git add .codex/agents/branch-depth-auditor.md .codex/agents/coverage-auditor.md +git commit -m "feat(codex): add branch-depth-auditor + coverage-auditor SSOT bodies" +``` + +--- + +## Task 6: 누락 agent 2개의 antigravity gated SSOT 본문 작성 + +> antigravity 본문 = codex 본문 + G1~G4 Gemini hard gate. 기존 read-only gated agent를 템플릿으로 사용한다. tool 참조는 antigravity 어휘(`view_file`/`grep_search`/`run_command`)로 쓴다. + +**Files:** +- Create: `.agents/plugins/wiki-superpowers/agents/branch-depth-auditor.md` +- Create: `.agents/plugins/wiki-superpowers/agents/coverage-auditor.md` + +- [ ] **Step 1: Study the gate template** + +Read `.agents/plugins/wiki-superpowers/agents/wiki-link-verifier.md` in full (read-only agent — closest analog). Extract the exact section structure of: G1 Pre-Read Proof, G2 Post-Write Validator, G3 Output Schema + V Counter, G4 Enumerated STOP Conditions. Also read `.agents/plugins/wiki-superpowers/agents/wiki-research-lane.md` if a longer analytical example helps. + +- [ ] **Step 2: Create `.agents/plugins/wiki-superpowers/agents/branch-depth-auditor.md`** + +```markdown +--- +name: branch-depth-auditor +description: +--- + + state "read-only agent, no file writes; + verification is the grep/sed verbatim-quote proofs inside the gap report (G3 V counter)". + - G3 Output Schema + V Counter: {{ }} placeholder schema for the Ready/Not-ready + verdict + per-axis gap rows; V = number of quote-grep commands actually run. + - G4 Enumerated STOP Conditions: numbered list -> return NEEDS_CONTEXT + (1: branch-note path missing/unreadable; 2: linked raw sources unreadable; + 3: wiki_structure_lint not yet passed; 4: target is not a feature-*.md branch note). + Use Antigravity tool names in any tool reference: view_file, grep_search, run_command.> +``` +Mirror the axes/ladder language from `.claude/agents/branch-depth-auditor.md`; do NOT invent new audit criteria. + +- [ ] **Step 3: Create `.agents/plugins/wiki-superpowers/agents/coverage-auditor.md`** + +Same structure. Coverage = completeness (covered-here / delegated / missing per required concern) with a 3-tier verdict and optional project mode. G4 STOP conditions: governing_docs missing, `## Coverage` section absent, links unresolved, target not a branch note. tool refs use `run_command` for grep-based concern classification + `view_file` for governing docs. + +- [ ] **Step 4: Verify frontmatter parses + all four gates present** + +Run: +```bash +cd /home/donghyeon/dev/llm-wiki-private +for n in branch-depth-auditor coverage-auditor; do + f=.agents/plugins/wiki-superpowers/agents/$n.md + echo "== $n ==" + grep -c "G1 Pre-Read Proof" "$f" + grep -c "G4" "$f" +done +``` +Expected: each `grep -c` prints `1` or more (gates present). If `0`, the gate section is missing — add it. + +- [ ] **Step 5: Commit** + +```bash +git add .agents/plugins/wiki-superpowers/agents/branch-depth-auditor.md .agents/plugins/wiki-superpowers/agents/coverage-auditor.md +git commit -m "feat(antigravity): add branch-depth-auditor + coverage-auditor gated SSOT bodies" +``` + +--- + +## Task 7: 전체 9개 생성 + 스키마 검증 + drift 0 확인 + +**Files:** +- Generate: `.codex/agents/*.toml` ×9, `.agents/agents//agent.json` ×9 +- Test: `scripts/test_sync_automation.py` (add a full-suite generation guard) + +- [ ] **Step 1: Add a test asserting all 9 generate and pass schema checks** + +```python +def test_all_nine_agents_generate_valid_artifacts(tmp_path, monkeypatch): + monkeypatch.setattr(s, "CODEX_AGENTS", tmp_path / "codex") + monkeypatch.setattr(s, "ANTIGRAV_OUT", tmp_path / "antigrav") + # copy SSOT bodies the generator reads from real repo (CODEX_AGENTS is also the source dir), + # so point the source dir explicitly: regenerate using real source via a fresh load. + (tmp_path / "codex").mkdir() + # NOTE: generate_one reads codex body from s.CODEX_AGENTS; for this test we only verify + # the antigravity side (json) which reads from ANTIGRAV_SSOT (unchanged real dir). + for name in s.AGENT_NAMES: + obj = s.build_antigravity_agent( + name, "d", + s.parse_frontmatter((s.ANTIGRAV_SSOT / f"{name}.md").read_text())[1], + s.parse_tools(s.parse_frontmatter((s.CLAUDE_AGENTS / f"{name}.md").read_text())[0]["tools"]), + ) + assert json.loads(s.render_json(obj))["name"] == name + # read-only agents must NOT carry write tools + ro = {"branch-depth-auditor", "coverage-auditor", "wiki-adversarial-reviewer", + "wiki-diagram-reviewer", "wiki-link-verifier", "wiki-research-lane"} + if name in ro: + assert "write_to_file" not in obj["config"]["customAgent"]["toolNames"], name +``` + +> 위 테스트는 `CODEX_AGENTS`/`ANTIGRAV_SSOT`의 9개 `.md`가 모두 존재해야 통과한다(Task 5·6 완료 후). codex toml 본문은 실 디렉토리에서 직접 읽으므로 통합 스모크(Step 3)로 검증한다. + +- [ ] **Step 2: Run the unit suite** + +Run: `cd scripts && python3 -m pytest test_sync_automation.py -v` +Expected: PASS (all, including the new 9-agent guard). + +- [ ] **Step 3: Generate all 9 and validate every artifact** + +Run: +```bash +cd /home/donghyeon/dev/llm-wiki-private +python3 scripts/sync_automation.py agents +echo "--- validate codex toml (9) ---" +python3 -c " +import tomllib, pathlib +ns=['branch-depth-auditor','coverage-auditor','wiki-adversarial-reviewer','wiki-decision-researcher','wiki-diagram-reviewer','wiki-doc-author','wiki-link-verifier','wiki-research-lane','wiki-source-summarizer'] +for n in ns: + o=tomllib.loads(pathlib.Path(f'.codex/agents/{n}.toml').read_text()) + assert o['name']==n and o['sandbox_mode'] in ('read-only','workspace-write') and o['developer_instructions'].strip() +print('codex toml ok:', len(ns)) +" +echo "--- validate antigravity json (9) ---" +python3 -c " +import json, pathlib +ns=['branch-depth-auditor','coverage-auditor','wiki-adversarial-reviewer','wiki-decision-researcher','wiki-diagram-reviewer','wiki-doc-author','wiki-link-verifier','wiki-research-lane','wiki-source-summarizer'] +for n in ns: + o=json.loads(pathlib.Path(f'.agents/agents/{n}/agent.json').read_text()) + ca=o['config']['customAgent'] + assert o['name']==n and o['hidden'] is True + assert ca['systemPromptSections'][0]['content'].strip() + assert ca['toolNames'][0]=='send_message' +print('antigravity json ok:', len(ns)) +" +``` +Expected: +``` +generated 9 agents (codex .toml + antigravity agent.json) +--- validate codex toml (9) --- +codex toml ok: 9 +--- validate antigravity json (9) --- +antigravity json ok: 9 +``` + +- [ ] **Step 4: Confirm idempotency / drift-0** + +Run: +```bash +cd /home/donghyeon/dev/llm-wiki-private +python3 scripts/sync_automation.py agents --check && echo "DRIFT-FREE" +``` +Expected: +``` +checked 9 agents (codex .toml + antigravity agent.json) +DRIFT-FREE +``` +(exit 0). If it prints `DRIFT detected`, re-run without `--check` and re-commit the generated files. + +- [ ] **Step 5: Commit generated artifacts** + +```bash +cd /home/donghyeon/dev/llm-wiki-private +git add scripts/test_sync_automation.py .codex/agents/*.toml .agents/agents/ +git commit -m "feat(sync): generate all 9 agents for codex (.toml) + antigravity (agent.json)" +``` + +--- + +## Task 8: 생성 스크립트 사용법 문서 1단락 (codex + antigravity README) + +> 전체 문서 정리(CLAUDE.md의 구식 '수동 cat' 서술 제거 등)는 Phase 2. 여기서는 Phase 0가 만든 스크립트/산출물이 고아가 되지 않도록 최소 포인터만 추가한다. + +**Files:** +- Modify: `.codex/agents/README.md` +- Modify: `.agents/plugins/wiki-superpowers/README.md` + +- [ ] **Step 1: Add a "Native generation" note to `.codex/agents/README.md`** + +기존 README 상단(또는 "Pattern" 섹션 위)에 다음 취지의 1단락 추가 (정확한 문구는 기존 톤에 맞춰 작성): +- codex는 이제 native subagent를 `.codex/agents/*.toml`로 자동 등록한다(`developer_instructions`+`sandbox_mode`). `.md`는 사람이 편집하는 SSOT이고 `.toml`은 `python3 scripts/sync_automation.py agents`로 생성된다. +- `.md` 편집 후 반드시 `sync_automation.py agents`를 다시 돌려야 `.toml`에 반영된다. CI/hook에서는 `--check`로 drift를 검사한다. + +- [ ] **Step 2: Add the same note to `.agents/plugins/wiki-superpowers/README.md`** + +기존 "⚠️ Loading model" 박스의 "Sync command" 줄을 실제 스크립트로 교체: +- 구: `python3 .agents/scripts/convert-wiki-agents.py` (존재하지 않음) +- 신: `python3 scripts/sync_automation.py agents` — `.agents/plugins/.../agents/*.md`(gated SSOT) + `.claude/agents/*.md`(권한 SSOT) → `.agents/agents//agent.json` 생성. `--check`로 drift 검사. + +- [ ] **Step 3: Verify the dead reference is gone** + +Run: +```bash +cd /home/donghyeon/dev/llm-wiki-private +grep -rn "convert-wiki-agents.py" .agents/ .codex/ CLAUDE.md || echo "no dead reference remaining in README scope" +``` +Expected: `no dead reference remaining in README scope` (CLAUDE.md 본문의 언급은 Phase 2에서 처리하므로, 여기서 grep이 CLAUDE.md만 남기면 그 줄은 Phase 2 TODO로 남겨도 됨 — 단 README 2개에는 남지 않아야 함). + +- [ ] **Step 4: Commit** + +```bash +git add .codex/agents/README.md .agents/plugins/wiki-superpowers/README.md +git commit -m "docs(sync): point READMEs at scripts/sync_automation.py (replaces missing convert script)" +``` + +--- + +## Phase 0 완료 기준 (Definition of Done) + +- `scripts/sync_automation.py` + 테스트 통과(pytest green). +- `.codex/agents/*.toml` 9개 + `.agents/agents//agent.json` 9개 생성·검증. +- `sync_automation.py agents --check` 가 exit 0 (drift 0). +- 누락 2개 agent(branch-depth-auditor·coverage-auditor)가 codex·antigravity 양쪽 SSOT + 생성물에 존재. +- README 2개가 실제 생성 스크립트를 가리킴. +- 검증된 부채 수정: read-only agent의 `agent.json`에 write 도구 없음(stale 디스크 버그 해소). + +이후: **Phase 1**(commands → codex `.agents/skills/` + antigravity `.agents/workflows/`)는 별도 plan으로 작성한다. Phase 0의 `sync_automation.py`에 `commands` 타깃을 확장한다. + +--- + +## Self-Review (작성자 체크) + +- **Spec coverage**: 설계 §4 Phase 0(엔진+agents)의 모든 항목 — 생성 엔진, 9개 agent 생성, 누락 2개 추가, antigravity 로딩 경로 복구(agent.json+스크립트), codex toml 현대화 — 각각 Task 1~8에 매핑됨. Phase 1·2는 범위 밖(별도 plan). +- **Placeholder scan**: 코드 스텝은 실제 코드 포함. Task 5·6의 본문 작성은 "기존 파일을 템플릿으로 verbatim 적응"이라는 결정론적 절차 + 검증 grep을 제공(프로즈 자체는 SSOT 적응이라 코드처럼 박제 불가하나, 입력 파일·치환 규칙·검증 명령을 명시). +- **Type consistency**: 함수 시그니처 일관 — `parse_frontmatter`→`(fm,body)`, `antigravity_tool_names(tools)`, `render_codex_toml(name,description,sandbox_mode,body)`, `build_antigravity_agent(name,description,body,tools)`, `generate_one(name,check,drift)`. 모든 Task에서 동일 이름 사용. 모듈명 `sync_automation`(언더스코어)로 통일. +- **알려진 한계**: Task 7 Step 1 테스트는 codex toml 본문을 실디렉토리에서 읽어 통합 스모크(Step 3)로 보완. Task 6 Step 4의 grep 카운트는 게이트 "존재"만 보장하고 의미적 정확성은 보장하지 않음 → 실제 antigravity 실행 스모크는 Phase 1 검증과 함께 수행 권장. diff --git a/docs/superpowers/plans/2026-06-04-three-platform-sync-phase1-commands.md b/docs/superpowers/plans/2026-06-04-three-platform-sync-phase1-commands.md new file mode 100644 index 0000000..b75f79a --- /dev/null +++ b/docs/superpowers/plans/2026-06-04-three-platform-sync-phase1-commands.md @@ -0,0 +1,470 @@ +# 3-플랫폼 동기화 Phase 1 — commands Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Claude의 13개 슬래시 command(`.claude/commands/*.md`)를 Codex CLI **skills**(`.agents/skills//SKILL.md`)와 Antigravity CLI **workflows**(`.agents/workflows/.md`)로 생성하는 기능을 `scripts/sync_automation.py` 에 `commands` 타깃으로 추가한다. + +**Architecture:** Phase 0의 SSOT→생성 모델을 commands로 확장한다. SSOT = `.claude/commands/.md`(frontmatter `description`+`argument-hint` + 본문). 생성기는 (1) frontmatter를 플랫폼별 헤더로 변환, (2) `$ARGUMENTS` 토큰을 자연어 각괄호 인자(`argument-hint` 값)로 치환, (3) 본문의 platform-neutral 절차는 그대로 보존, (4) codex skill / antigravity workflow 두 포맷으로 직렬화한다. command 본문은 agent 본문과 달리 Claude 전용 tool 표현(`Read tool` 등)을 쓰지 않고 절차적 prose + shell + 서브에이전트 이름(Phase 0에서 3 플랫폼에 모두 포팅됨)만 참조하므로 기계 변환이 충분하다. + +**Tech Stack:** Python 3.12 (stdlib), pytest (venv: `/home/donghyeon/dev/llm-wiki-private/.venv/bin/python`). + +--- + +## 배경 / 확정된 포맷 사실 (공식문서 + 리서치) + +- **Codex skills** (`developers.openai.com/codex/skills`): 디스커버리 `/.agents/skills//SKILL.md`(repo 커밋). frontmatter 필수 2필드 `name`(폴더명과 일치 권장) + `description`(언제 발동). **인자 placeholder 없음 — 자연어로 전달**(`$ARGUMENTS`/`$1` 미지원). `/skills` picker 또는 `$name` 멘션으로 명시 호출 + description 의미 매칭. +- **Antigravity workflows** (Google Codelabs / atamel.dev): `/.agents/workflows/.md`, frontmatter **`description`만**(name=파일명), 본문은 prose 지시, 인자는 `` 식 각괄호 prose(placeholder 없음), `/ ` 호출. + - Codelab 실제 예시(verbatim): + ``` + --- + description: Start the Autonomous AI Developer Pipeline sequence with a new idea + --- + + When the user types `/startcycle `, orchestrate the development process ... + ``` +- **경로 규약 결정**: 이 repo는 이미 `.agents/`(복수) 규약(`​.agents/agents/`, `.agents/hooks.json`)을 쓰고 antigravity가 그것을 로드 중 → **antigravity workflows도 `.agents/workflows/`(복수)** 로 통일. codex skills는 공식 고정 경로 `.agents/skills/`. +- **알려진 충돌(미해결, 경험적 확인 필요)**: 일부 antigravity 빌드는 `.agents/skills/`도 skill로 읽어, codex command-skill이 antigravity에 semantic-trigger skill로 *이중 등록*될 수 있음(workflow + skill). 공식문서로 확정 불가 → **Task 1에서 실제 설치된 CLI로 경험적 확인** 후 필요 시 완화. + +### 13개 command (SSOT: `.claude/commands/*.md`) +`blogify` · `branch` · `branch-spec` · `coverage` · `daily` · `depth` · `ingest` · `interviewize` · `lint` · `migrate-claims` · `projectize` · `query` · `tag` + +frontmatter 공통: `description:` + `argument-hint:`. 본문은 `$ARGUMENTS` 토큰 + 절차(`## 작업 절차`) + 규칙. 일부는 `.claude/hooks/wiki_structure_lint.py`(실제 repo 스크립트, 크로스플랫폼 실행 가능 — 유지)와 포팅된 서브에이전트(`branch-depth-auditor` 등) 참조. + +--- + +## File Structure + +- Modify: `scripts/sync_automation.py` — `COMMAND_NAMES` 리스트, command frontmatter 파서 재사용(`parse_frontmatter`), `transform_command_body`, `render_codex_skill`, `render_antigravity_workflow`, `generate_command_one`, `main()` 의 `target` choices에 `commands` 추가. +- Modify: `scripts/test_sync_automation.py` — command 변환 단위 테스트. +- Create (생성물): `.agents/skills//SKILL.md` ×13 (codex), `.agents/workflows/.md` ×13 (antigravity). +- Create: `docs/superpowers/notes/2026-06-04-phase1-empirical-format-check.md` — Task 1 경험적 확인 결과 기록. +- Modify (말미): `CLAUDE.md` §2 표 + `.codex/agents/README.md` — commands→skills/workflows 매핑 1단락. + +> 책임 경계: 생성기는 frontmatter 변환 + `$ARGUMENTS` 치환 + 포맷 직렬화만. 본문 절차 prose는 platform-neutral이므로 보존. codex skill 본문에서 antigravity 전용 표기를 만들지 않고, antigravity workflow 본문에서 codex 전용 표기를 만들지 않는다(생성기가 플랫폼별로 분기). + +--- + +## Task 1: 경험적 포맷·충돌 확인 + 결정 잠금 + +**Files:** +- Create: `docs/superpowers/notes/2026-04-phase1-empirical-format-check.md` (디렉토리 없으면 생성) + +> 목적: 공식문서가 확정 못한 두 가지를 실제 설치된 CLI로 확인하고, 생성기 타깃 경로/인자 규약을 잠근다. CLI가 없으면 "가정 + 보류" 로 명시 기록(생성물은 가정대로 진행, 추후 검증). + +- [ ] **Step 1: 설치 여부 확인** + +```bash +cd /home/donghyeon/dev/llm-wiki-private +command -v codex && codex --version 2>&1 | head -1 || echo "codex: NOT INSTALLED" +ls -d ~/.gemini/antigravity-cli 2>/dev/null && echo "antigravity-cli home present" || echo "antigravity: home absent" +command -v agy 2>&1 || echo "agy (antigravity CLI) not on PATH" +``` + +- [ ] **Step 2: (codex 있으면) skill 디스커버리 경로 확인** + +scratch skill을 만들어 codex가 `.agents/skills/`를 읽는지 확인: +```bash +mkdir -p /tmp/codex-skill-probe/.agents/skills/probe-skill +printf -- '---\nname: probe-skill\ndescription: probe codex skill discovery\n---\nprobe body\n' > /tmp/codex-skill-probe/.agents/skills/probe-skill/SKILL.md +# codex의 skills 목록 확인 (codex 설치 시): 예) `codex` TUI에서 /skills, 또는 가능한 CLI 서브커맨드 +codex --help 2>&1 | grep -iE "skill|prompt" || echo "no skill subcommand surfaced in --help" +``` +결과(읽힘/안읽힘/불명)를 노트에 기록. + +- [ ] **Step 3: (antigravity 있으면) `.agents/skills/` 이중 로드 여부 확인** + +antigravity가 `.agents/skills/`를 skill로 읽는지(=codex command-skill 이중 등록 위험) 실제 빌드에서 확인. 가능한 방법: antigravity CLI의 skill/workflow 목록 출력 커맨드, 또는 `~/.gemini/antigravity-cli/` 로그/registry 확인. 결과를 노트에 기록. + +- [ ] **Step 4: 결정 기록** + +노트에 다음을 표로 확정(경험 결과 또는 "UNVERIFIED — 가정"): +| 항목 | 결정 | 근거 | +|---|---|---| +| codex skill 경로 | `.agents/skills//SKILL.md` | 공식 디스커버리 경로 | +| antigravity workflow 경로 | `.agents/workflows/.md` | repo `.agents/` 복수 규약 일치 | +| `$ARGUMENTS` 매핑 | argument-hint 각괄호 prose로 치환 | 양 플랫폼 placeholder 미지원 | +| `.agents/skills/` antigravity 이중로드 | {{읽음→완화 필요 / 안읽음→무관 / UNVERIFIED}} | Step 3 결과 | + +- [ ] **Step 5: Commit** + +```bash +cd /home/donghyeon/dev/llm-wiki-private +git add docs/superpowers/notes/ +git commit -m "docs(phase1): empirical format + skills-collision check, lock target paths" +``` + +--- + +## Task 2: command 파싱 + skill/workflow 직렬화 (순수 함수, TDD) + +**Files:** +- Modify: `scripts/sync_automation.py` +- Test: `scripts/test_sync_automation.py` + +- [ ] **Step 1: Write the failing test** + +```python +# append to scripts/test_sync_automation.py + +_SAMPLE_CMD = ( + "---\n" + "description: 브랜치 노트의 구현 착수 깊이 점검\n" + "argument-hint: <브랜치 이름>\n" + "---\n\n" + "브랜치 노트 1개의 깊이를 점검합니다.\n\n" + "**브랜치 이름:** $ARGUMENTS\n\n" + "## 작업 절차\n1. `branch-depth-auditor` 서브에이전트를 디스패치한다.\n" +) + + +def test_transform_command_body_replaces_arguments(): + out = s.transform_command_body(_body_of(_SAMPLE_CMD), "<브랜치 이름>") + assert "$ARGUMENTS" not in out + assert "<브랜치 이름>" in out + # platform-neutral 절차/에이전트 참조는 보존 + assert "branch-depth-auditor 서브에이전트를 디스패치" in out + + +def test_render_codex_skill_frontmatter(): + out = s.render_codex_skill( + name="depth", + description="브랜치 노트의 구현 착수 깊이 점검", + arg_hint="<브랜치 이름>", + body="**브랜치 이름:** <브랜치 이름>\n\n## 작업 절차\n1. ...\n", + ) + fm, body = s.parse_frontmatter(out) + assert fm["name"] == "depth" + assert fm["description"] # non-empty + assert "$ARGUMENTS" not in body + assert "## 작업 절차" in body + + +def test_render_antigravity_workflow_frontmatter_and_invocation(): + out = s.render_antigravity_workflow( + name="depth", + description="브랜치 노트의 구현 착수 깊이 점검", + arg_hint="<브랜치 이름>", + body="## 작업 절차\n1. ...\n", + ) + fm, body = s.parse_frontmatter(out) + assert set(fm.keys()) == {"description"} # name comes from filename, not frontmatter + # 호출 안내가 본문 상단에 있어야 함 (Codelab 패턴) + assert "/depth <브랜치 이름>" in body + assert "## 작업 절차" in body +``` + +(헬퍼 `_body_of` 는 테스트 상단에 추가: `def _body_of(md): return s.parse_frontmatter(md)[1]`.) + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd /home/donghyeon/dev/llm-wiki-private && .venv/bin/python -m pytest scripts/test_sync_automation.py -k "command or codex_skill or workflow" -v` +Expected: FAIL with `AttributeError: ... 'transform_command_body'`. + +- [ ] **Step 3: Write minimal implementation** + +```python +# add near COMMAND-related code in sync_automation.py + +COMMAND_NAMES = [ + "blogify", "branch", "branch-spec", "coverage", "daily", "depth", + "ingest", "interviewize", "lint", "migrate-claims", "projectize", + "query", "tag", +] + +CLAUDE_COMMANDS = REPO / ".claude" / "commands" +CODEX_SKILLS = REPO / ".agents" / "skills" +ANTIGRAV_WORKFLOWS = REPO / ".agents" / "workflows" + + +def transform_command_body(body: str, arg_hint: str) -> str: + # Neither Codex skills nor Antigravity workflows support a $ARGUMENTS + # placeholder; both take arguments as natural language. Replace the token + # with the argument-hint's angle-bracket prose so the body still reads well. + return body.replace("$ARGUMENTS", arg_hint) + + +def render_codex_skill(name: str, description: str, arg_hint: str, body: str) -> str: + # description drives implicit trigger; fold in the arg hint for clarity. + desc = f"{description} (입력: {arg_hint})" + return ( + "---\n" + f"name: {name}\n" + f"description: {desc}\n" + "---\n\n" + f"{body.rstrip()}\n" + ) + + +def render_antigravity_workflow(name: str, description: str, arg_hint: str, body: str) -> str: + invocation = f"사용자가 `/{name} {arg_hint}` 를 입력하면 아래 절차를 수행한다.\n\n" + return ( + "---\n" + f"description: {description}\n" + "---\n\n" + f"{invocation}{body.rstrip()}\n" + ) +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `cd /home/donghyeon/dev/llm-wiki-private && .venv/bin/python -m pytest scripts/test_sync_automation.py -k "command or codex_skill or workflow" -v` +Expected: PASS. + +- [ ] **Step 5: Commit** + +```bash +cd /home/donghyeon/dev/llm-wiki-private +git add scripts/sync_automation.py scripts/test_sync_automation.py +git commit -m "feat(sync): command body transform + codex skill / antigravity workflow renderers" +``` + +--- + +## Task 3: command 로더 + CLI `commands` 타깃 (TDD) + +**Files:** +- Modify: `scripts/sync_automation.py` +- Test: `scripts/test_sync_automation.py` + +- [ ] **Step 1: Write the failing test** + +```python +def test_load_command_inputs_for_existing_command(): + ci = s.load_command_inputs("depth") + assert ci.name == "depth" + assert ci.description + assert ci.arg_hint.startswith("<") or "--" in ci.arg_hint + assert "$ARGUMENTS" in ci.body or "작업 절차" in ci.body # raw body still has token + + +def test_generate_command_writes_both(tmp_path, monkeypatch): + monkeypatch.setattr(s, "CODEX_SKILLS", tmp_path / "skills") + monkeypatch.setattr(s, "ANTIGRAV_WORKFLOWS", tmp_path / "workflows") + s.generate_command_one("depth", check=False) + skill = tmp_path / "skills" / "depth" / "SKILL.md" + wf = tmp_path / "workflows" / "depth.md" + assert skill.exists() and wf.exists() + sfm, sbody = s.parse_frontmatter(skill.read_text()) + assert sfm["name"] == "depth" and "$ARGUMENTS" not in sbody + wfm, wbody = s.parse_frontmatter(wf.read_text()) + assert "/depth" in wbody and "$ARGUMENTS" not in wbody + + +def test_main_commands_target_check_is_clean_after_generate(): + # after generation (Task 4), --check must be drift-free + rc = s.main(["commands", "--check"]) + assert rc == 0 +``` + +> 마지막 테스트는 Task 4 생성 이후에만 통과한다. Task 3 단계에서는 앞 두 테스트만 대상으로 실행하고, 세 번째는 Task 4 검증에서 green 확인. + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd /home/donghyeon/dev/llm-wiki-private && .venv/bin/python -m pytest scripts/test_sync_automation.py -k "load_command or generate_command" -v` +Expected: FAIL with `AttributeError: ... 'load_command_inputs'`. + +- [ ] **Step 3: Write minimal implementation** + +```python +@dataclass +class CommandInputs: + name: str + description: str + arg_hint: str + body: str + + +def load_command_inputs(name: str) -> CommandInputs: + fm, body = parse_frontmatter((CLAUDE_COMMANDS / f"{name}.md").read_text()) + return CommandInputs( + name=name, + description=fm.get("description", "").strip(), + arg_hint=fm.get("argument-hint", "").strip(), + body=body, + ) + + +def generate_command_one(name: str, check: bool, drift: list[str] | None = None) -> None: + drift = drift if drift is not None else [] + ci = load_command_inputs(name) + tbody = transform_command_body(ci.body, ci.arg_hint) + skill_text = render_codex_skill(ci.name, ci.description, ci.arg_hint, tbody) + wf_text = render_antigravity_workflow(ci.name, ci.description, ci.arg_hint, tbody) + _write_or_check(CODEX_SKILLS / name / "SKILL.md", skill_text, check, drift) + _write_or_check(ANTIGRAV_WORKFLOWS / f"{name}.md", wf_text, check, drift) +``` + +그리고 `main()` 을 확장: `target` choices에 `commands` 추가하고 분기. + +```python +def main(argv: list[str] | None = None) -> int: + ap = argparse.ArgumentParser(description="Sync Claude agents/commands -> Codex/Antigravity native files") + ap.add_argument("target", choices=["agents", "commands"], help="what to sync") + ap.add_argument("--check", action="store_true", help="fail (exit 2) if outputs drift from SSOT") + ap.add_argument("--only", help="single name (default: all)") + args = ap.parse_args(argv) + + if args.target == "agents": + names = [args.only] if args.only else AGENT_NAMES + gen = generate_one + label = "agents (codex .toml + antigravity agent.json)" + else: + names = [args.only] if args.only else COMMAND_NAMES + gen = generate_command_one + label = "commands (codex skill + antigravity workflow)" + + drift: list[str] = [] + for name in names: + try: + gen(name, check=args.check, drift=drift) + except FileNotFoundError as e: + print(f"ERROR: missing SSOT for '{name}': {e.filename}", file=sys.stderr) + return 1 + if args.check and drift: + print("DRIFT detected in:\n " + "\n ".join(drift), file=sys.stderr) + return 2 + action = "checked" if args.check else "generated" + print(f"{action} {len(names)} {label}") + return 0 +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `cd /home/donghyeon/dev/llm-wiki-private && .venv/bin/python -m pytest scripts/test_sync_automation.py -k "load_command or generate_command" -v` +Expected: PASS. Also run the FULL suite to confirm the `main()` refactor didn't break agents: +Run: `.venv/bin/python -m pytest scripts/test_sync_automation.py -q` +Expected: all green. Then sanity: `python3 scripts/sync_automation.py agents --check` still exits 0. + +- [ ] **Step 5: Commit** + +```bash +cd /home/donghyeon/dev/llm-wiki-private +git add scripts/sync_automation.py scripts/test_sync_automation.py +git commit -m "feat(sync): commands target — load + generate codex skills / antigravity workflows" +``` + +--- + +## Task 4: 13개 command 전체 생성 + 검증 + drift-0 + +**Files:** +- Generate: `.agents/skills//SKILL.md` ×13, `.agents/workflows/.md` ×13 + +- [ ] **Step 1: 생성 + 검증** + +```bash +cd /home/donghyeon/dev/llm-wiki-private +python3 scripts/sync_automation.py commands +echo "--- counts ---" +echo "skills: $(ls .agents/skills/*/SKILL.md | wc -l) | workflows: $(ls .agents/workflows/*.md | wc -l)" +echo "--- validate ---" +.venv/bin/python -c " +import sys; sys.path.insert(0,'scripts'); import sync_automation as s +for n in s.COMMAND_NAMES: + sfm,sbody=s.parse_frontmatter(open(f'.agents/skills/{n}/SKILL.md').read()) + assert sfm['name']==n and sfm['description'] and '\$ARGUMENTS' not in sbody, n + wfm,wbody=s.parse_frontmatter(open(f'.agents/workflows/{n}.md').read()) + assert 'description' in wfm and f'/{n}' in wbody and '\$ARGUMENTS' not in wbody, n +print('all 13 commands ok (skill name+desc, workflow desc+invocation, no \$ARGUMENTS)') +" +echo "--- no {{ }} placeholders leaked into workflows (antigravity G3) ---" +! grep -l '{{' .agents/workflows/*.md || echo "WARNING: {{ }} found" +``` +Expected: `skills: 13 | workflows: 13`, validation ok, no `{{` warning. + +- [ ] **Step 2: drift-0** + +```bash +cd /home/donghyeon/dev/llm-wiki-private +python3 scripts/sync_automation.py commands --check; echo "exit=$?" +``` +Expected: `checked 13 commands ...` + `exit=0`. + +- [ ] **Step 3: 전체 테스트(세 번째 main commands check 테스트 포함)** + +Run: `.venv/bin/python -m pytest scripts/test_sync_automation.py -q` +Expected: all green. + +- [ ] **Step 4: Commit** + +```bash +cd /home/donghyeon/dev/llm-wiki-private +git add .agents/skills/ .agents/workflows/ +git commit -m "feat(sync): generate 13 commands as codex skills + antigravity workflows" +``` + +--- + +## Task 5: 대표 command 실호출 스모크 (CLI 있으면) + +> Phase 0 agents와 달리 commands는 사용자가 실제로 호출하는 표면이므로, 설치된 CLI에서 1~2개를 실호출해 형식이 맞는지 확인한다. CLI 미설치면 SKIP + 노트 기록. + +- [ ] **Step 1: codex skill 인식 확인 (codex 있으면)** + +`.agents/skills/depth/SKILL.md` 가 codex의 `/skills` 또는 `$depth` 로 인식되는지 확인. 인식 안 되면 frontmatter/경로를 Task 1 노트와 대조해 진단. + +- [ ] **Step 2: antigravity workflow 인식 확인 (antigravity 있으면)** + +`.agents/workflows/depth.md` 가 antigravity에서 `/depth` 로 등록되는지 확인. 동시에 Task 1의 이중로드 가설(코덱스 skill이 antigravity에 새는지)을 `/skills` 목록으로 재확인. + +- [ ] **Step 3: 결과를 Task 1 노트에 추가 기록 + (필요 시) 완화** + +- 이중로드가 실제로 발생하고 바람직하지 않으면: 완화안을 노트에 적고 사용자에게 에스컬레이션(예: codex skill만 두고 antigravity는 workflow만 쓰도록 build 설정, 또는 경로 분리). **이 단계에서 임의로 큰 구조 변경하지 말 것** — 결과만 보고. + +- [ ] **Step 4: Commit (노트 갱신 시)** + +```bash +cd /home/donghyeon/dev/llm-wiki-private +git add docs/superpowers/notes/ +git commit -m "docs(phase1): empirical smoke results for codex skills / antigravity workflows" +``` + +--- + +## Task 6: 문서 갱신 (commands→skills/workflows 매핑) + +**Files:** +- Modify: `CLAUDE.md` (§2 디렉터리 역할 표 또는 자동화 섹션) +- Modify: `.codex/agents/README.md` + +- [ ] **Step 1: CLAUDE.md 에 1단락** + +§2의 자동화 목록에 codex/antigravity의 command 등가물을 명시: +- Codex: `.agents/skills//SKILL.md` (13개, `$cmd` 호출), 생성 `python3 scripts/sync_automation.py commands`. +- Antigravity: `.agents/workflows/.md` (13개, `/cmd` 호출). +- 인자는 placeholder 없이 자연어(각괄호 prose). + +- [ ] **Step 2: `.codex/agents/README.md` 의 "Native generation" 노트에 commands 줄 추가** + +`sync_automation.py commands` 로 13개 command가 `.agents/skills/`(codex) + `.agents/workflows/`(antigravity)에 생성됨을 1줄 추가. + +- [ ] **Step 3: 검증 + Commit** + +```bash +cd /home/donghyeon/dev/llm-wiki-private +grep -c "sync_automation.py commands" CLAUDE.md .codex/agents/README.md +git add CLAUDE.md .codex/agents/README.md +git commit -m "docs(sync): document commands -> codex skills + antigravity workflows" +``` + +--- + +## Phase 1 완료 기준 (Definition of Done) + +- `sync_automation.py commands` 타깃 동작 + 테스트 green. +- `.agents/skills//SKILL.md` 13개 + `.agents/workflows/.md` 13개 생성·검증. +- `python3 scripts/sync_automation.py commands --check` exit 0 (drift 0). +- `$ARGUMENTS` 토큰이 생성물에 0개, antigravity workflow에 `{{ }}` 0개. +- Task 1/5 경험적 확인 결과가 노트에 기록(또는 CLI 미설치 시 가정으로 명시). +- CLAUDE.md + codex README에 매핑 문서화. + +이후: **Phase 2**(hooks → `.codex/hooks.json`, `AGENTS.md`, CLAUDE.md의 구식 codex "수동 cat" 서술 정리 — line 76)는 별도 plan. + +--- + +## Self-Review (작성자 체크) + +- **Spec coverage**: 설계 §4 Phase 1(commands → codex skills + antigravity workflows, 생성기 commands 타깃 확장)의 모든 요소가 Task 2~4에 매핑. 설계 §6 리스크의 `.agents/skills/` 충돌은 Task 1/5 경험적 확인으로 처리. +- **Placeholder scan**: 코드 스텝은 실제 코드 포함. Task 1/5는 경험적 절차라 결과가 환경 의존 — 명령 + 기록 표 + "UNVERIFIED 시 가정 명시" 로 결정론화. +- **Type consistency**: `transform_command_body(body, arg_hint)`, `render_codex_skill(name,description,arg_hint,body)`, `render_antigravity_workflow(name,description,arg_hint,body)`, `CommandInputs`, `load_command_inputs(name)`, `generate_command_one(name,check,drift)` — 전 Task 일관. `_write_or_check`/`parse_frontmatter`는 Phase 0 함수 재사용. +- **알려진 한계**: command 본문이 platform-neutral하다는 가정에 의존(실측: `.claude/commands/*.md`는 `Read tool` 류 미사용, shell·서브에이전트명·repo 경로만 참조). 만약 특정 command가 Claude 전용 표기를 쓰면 그 command만 생성 후 hand-review 필요 — Task 4 검증의 `$ARGUMENTS`/`{{`grep으로 1차 포착. diff --git a/docs/superpowers/plans/2026-06-04-three-platform-sync-phase2-hooks-agentsmd.md b/docs/superpowers/plans/2026-06-04-three-platform-sync-phase2-hooks-agentsmd.md new file mode 100644 index 0000000..c1819dd --- /dev/null +++ b/docs/superpowers/plans/2026-06-04-three-platform-sync-phase2-hooks-agentsmd.md @@ -0,0 +1,298 @@ +# 3-플랫폼 동기화 Phase 2 (마지막) — hooks + 프로젝트 지침 + 정리 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans. Steps use checkbox (`- [ ]`) syntax. + +**Goal:** Claude의 결정론 훅(`wiki_structure_lint.py` 구조 린트 + `wiki_claim_gate.py` claim 게이트)을 Codex CLI(`.codex/hooks.json`)에 연결하고, 세 플랫폼이 동일한 프로젝트 지침(`CLAUDE.md`)을 읽도록 codex `AGENTS.md`/config를 구성하며, Phase 0~1에서 생긴 문서 잔여를 정리해 동기화를 완결한다. + +**Architecture:** 훅 스크립트는 이미 멀티-variant 입력 리더(`tool_name` / `tool_call.name`)를 갖췄지만 *차단 규약*과 *출력 스키마*가 플랫폼마다 다르다(Claude: exit 2+stderr / Antigravity: `{decision:deny}` JSON / Codex: 경험적 확인 필요). 따라서 Phase 2는 **(1) 이식성 버그 선수정**(claim_gate 하드코딩 ROOT) → **(2) codex 훅 payload·차단 규약 경험적 캡처**(codex 설치됨) → **(3) `.codex/hooks.json` 배선 + 필요 시 codex-variant 어댑트** → **(4) 프로젝트 지침 DRY 구성** → **(5) CLAUDE.md 잔여 정리** 순으로 간다. 훅 *스크립트 SSOT* 는 `.claude/hooks/` 1벌을 유지하고 플랫폼별 config 가 그것을 가리킨다(스크립트 중복 금지). + +**Tech Stack:** Python 3.12, codex-cli 0.136.0, agy(Antigravity), pytest(venv). + +--- + +## 배경 / 현재 훅 지형 (실측) + +| 훅 | 위치 | root 해석 | 입력 | 차단 규약 | +|---|---|---|---|---| +| `wiki_structure_lint.py` | `.claude/hooks/` | `DEFAULT_ROOT = SCRIPT.parents[2]` (동적·이식 OK) | `--hook`(stdin JSON→file_path, C2 non-blocking) / `--file` / `--all` | non-blocking(경고) | +| `wiki_claim_gate.py` | `.claude/hooks/` | **`ROOT=Path("/home/donghyeon/Documents/LLM Wiki")` 하드코딩 — 이 repo 경로 아님(버그)** | stdin JSON (`tool_name`/`tool_call.name`/`hook_event_name`) | Claude: exit 2 + stderr | +| `wiki_hard_gate.py` | `~/.gemini/antigravity-cli/hooks/` (global) | — | antigravity protobuf (`tool_call.{name,input}`) | Antigravity: stdout `{decision:"deny"}` | + +- Claude `.claude/settings.json`: PreToolUse(claim_gate, matcher `*`) + PostToolUse(structure_lint `--hook`, matcher `Write|Edit|MultiEdit`) + SubagentStart/Stop(claim_gate). 명령은 `python3 "$CLAUDE_PROJECT_DIR"/.claude/hooks/` will not work." + +> [§CSP against XSS] "By preventing the page from loading scripts from arbitrary servers, attacks like injecting `` will not work." + +> [§Introduction] "A strong CSP provides an effective second layer of protection against various types of vulnerabilities, especially XSS." + +## Claims Extracted / 추출된 주장 + +> 이 자료가 **직접 말하는 것만** claim 으로 분리한다. 내 프로젝트 적용 결론은 아래에 포함하지 않는다. + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| OWASP-CSP-C1 | CSP 는 web server 가 보내는 `Content-Security-Policy` **HTTP response header** 로 전달된다 | [§How to use CSP] "Send a Content-Security-Policy HTTP response header from your web server." | `official-reference` (OWASP cheatsheet — W3C spec 별도) | CSP header 의 소유·전달 위치(server/hosting 응답 헤더) 판정 | frontend bundle 이 header 값을 결정한다는 뜻은 아님 — header 는 server/hosting 소유 | +| OWASP-CSP-C2 | `'unsafe-inline'` 은 inline script/style 사용을 허용한다; 즉 이 keyword 가 없으면 inline script 는 실행되지 않아 `` 주입이 무력화된다 | [§Directives] "'unsafe-inline' Allows the usage of inline scripts or styles." + [§CSP against XSS] "By preventing the page from executing inline scripts, attacks like injecting `` will not work." | `official-reference` | strict CSP 아래에서 bundle 이 inline script 를 피해야 하는 이유 | nonce/hash 로 특정 inline script 를 allowlist 하는 방식의 세부는 본 인용 범위 밖 | +| OWASP-CSP-C3 | `'unsafe-eval'` 은 script 안에서 `eval` 사용을 허용한다; 즉 이 keyword 가 없으면 `eval`/dynamic code 실행이 차단된다 | [§Directives] "'unsafe-eval' Allows the usage of eval in scripts." | `official-reference` | strict CSP 아래에서 bundle·의존성이 `eval`/`new Function` 을 피해야 하는 이유 | 어떤 라이브러리가 eval 을 쓰는지, 그 탐지 방법은 본 인용 범위 밖 | +| OWASP-CSP-C4 | strong CSP 는 XSS 등에 대한 **effective second layer(defense-in-depth)** 이며, arbitrary server 로부터의 script 로드를 막아 `` will not work." | `official-reference` | CSP 를 primary XSS 방어가 아닌 second layer 로 자리매김하는 판정(=frontend 의 injection 금지 default 가 여전히 primary) | CSP 만으로 XSS 가 완전히 방지된다는 뜻은 아님 — second layer | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것** (2026-07-19 WebFetch verbatim 확인): + - `OWASP-CSP-C1`: CSP 는 HTTP response header 로 전달(서버/hosting 소유). + - `OWASP-CSP-C2`: `'unsafe-inline'` 이 inline script/style 을 허용하며, 없으면 inline script 실행 차단. + - `OWASP-CSP-C3`: `'unsafe-eval'` 이 `eval` 을 허용하며, 없으면 `eval`/dynamic code 차단. + - `OWASP-CSP-C4`: CSP 는 XSS 에 대한 second layer(defense-in-depth)이고 arbitrary-source script 로드를 차단. +- **이 자료가 증명하지 않는 것**: + - 특정 프로젝트가 사용해야 할 정확한 directive 집합(`default-src 'self'` 등) — 배포 환경·hosting 정책 의존, header owner 결정. + - CSP 만으로 XSS 가 완전히 방지된다는 명제 — second layer 임을 명시. + - nonce/hash 기반 inline script allowlist 의 구체 문법 — 본 인용 범위 밖. + - HSTS/frame/referrer 등 다른 security header 정책 — 별도 문서(OWASP HSTS cheat sheet 등). +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-skeleton-frontend bundle 과 그 의존성이 실제로 inline script/eval 을 요구하지 않는지 build 산출물 검사(compatibility fixture). + - 실제 CSP directive 값은 hosting/backend header owner branch(release·cache·header 정책) 가 정의 — 본 branch 는 값이 아닌 compatibility 만 검증. + +## 메모 / Notes + +> 본 섹션은 자료 직접 인용 아님. ca-skeleton-frontend 해석. + +- **header 소유 경계**: `OWASP-CSP-C1`이 "CSP는 server가 보내는 응답 header"라고 명시하므로, ca-skeleton-frontend에서 CSP directive 값은 hosting/backend header owner 소유다. `feature-frontend-browser-security-boundary-contract`는 값이 아니라 *bundle이 그 정책과 호환되는가*(inline script/eval 미의존)만 책임진다. +- **second layer 위치**: `OWASP-CSP-C4`가 CSP를 "second layer"로 규정하므로, injection 기본 금지(lint)와 output encoding이 primary 방어로 남고 CSP는 보완이다. CSP가 있으니 injection lint를 완화해도 된다고 해석하면 안 된다. +- **nonce/hash**: 불가피한 inline이 필요할 때 nonce/hash로 특정 script를 allowlist하는 방식은 본 cheatsheet 범위 밖이며 header owner 결정이다. skeleton default는 inline 자체를 만들지 않는 것. +- OWASP cheatsheet는 **권고이며 강제 표준이 아님**. W3C CSP spec이 normative. + +## Related / 관련 + +- 같은 주제 다른 official-doc: + - [[raw/official-docs/owasp-hsts-cheat-sheet]] — 다른 security response header(HSTS) + - [[raw/official-docs/owasp-html5-storage-xss-spa]] — browser storage 의 XSS 노출 +- 인용하는 branch: + - [[raw/branch-notes/feature-frontend-browser-security-boundary-contract]] +- 인용하는 project: + - [[raw/project-notes/ca-skeleton-frontend-operational-contract]] +- 인용하는 wiki: (미작성) + diff --git a/vault/20-evidence/official-docs/owasp-file-upload-cheat-sheet.md b/vault/20-evidence/official-docs/owasp-file-upload-cheat-sheet.md new file mode 100644 index 0000000..2679d03 --- /dev/null +++ b/vault/20-evidence/official-docs/owasp-file-upload-cheat-sheet.md @@ -0,0 +1,101 @@ +--- +title: OWASP File Upload Cheat Sheet — extension/content-type validation + storage isolation +source_type: official-doc +url: https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html +archive_url: +status: raw +confidence: high +related_branches: [feature-file-resource-handling-contract, feature-security-operational-baseline] +related_projects: [ca-skeleton-operational-contract] +tags: [ca-security, file-upload, owasp, extension-allowlist, content-type, storage-isolation, official-doc] +created: 2026-05-27 +last_reviewed: 2026-05-27 +--- + +# OWASP File Upload Cheat Sheet + +> Layer: `raw/official-docs/` — OWASP Foundation 발행 file upload security cheat sheet. ca-tmpl file resource handling contract D5 (file upload validation pipeline) 의 운영 원칙 reference. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-file-resource-handling-contract]] | D5 (file upload validation pipeline — extension allowlist, content-type 신뢰 금지, UUID 파일명, webroot 밖 저장, size limit, AV 스캔) 의 원칙별 1차 근거 | +| [[raw/branch-notes/feature-security-operational-baseline]] | upload endpoint 의 deny-by-default 원칙과 antivirus / sandboxing 운영 권고 근거 | + +## 컨텍스트 / 왜 저장했는지 + +ca-tmpl file resource handling contract 에서 "왜 Content-Type 헤더를 신뢰하면 안 되는가", "왜 원본 파일명을 보존하지 않고 UUID 로 rename 해야 하는가", "왜 파일을 webroot 밖에 저장해야 하는가" 결정의 1차 운영 원칙 출처. OWASP cheatsheet 는 표준 아니지만 광범위한 커뮤니티 합의를 가짐. + +## 출처 / Source + +- 원본 URL: https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html +- 아카이브 URL: (미수집) +- 저자 / 조직: OWASP Foundation (Cheat Sheet Series — 커뮤니티 합의 + foundation 발행) +- 발행일: rolling docs +- 마지막 확인일: 2026-05-27 (WebFetch verbatim 확인) + +## 핵심 인용 / Key quotes (verbatim, captured 2026-05-27) + +> [§Extension Validation] "List allowed extensions. Only allow safe and critical extensions for business functionality" + +> [§Content-Type Validation] "The Content-Type for uploaded files is provided by the user, and as such cannot be trusted, as it is trivial to spoof." + +> [§Filename Safety] "Creating a random string as a filename, such as generating a UUID/GUID, is essential." + +> [§File Storage Location] "Store the files on a different host, which allows for complete segregation of duties between the application serving the user, and the host handling file uploads and their storage." + +> [§File Storage Location] "Store the files outside the webroot, where only administrative access is allowed." + +> [§Upload and Download Limits] "The application should set proper size limits for the upload service in order to protect the file storage capacity." + +> [§Malicious Files] "Run the file through an antivirus or a sandbox if available to validate that it doesn't contain malicious data." + +> [§Filesystem Permissions] "Set the files permissions on the principle of least privilege." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| OWASP-FUP-C1 | 업로드 파일 extension 은 **allowlist** 로 관리 — business functionality 에 필요한 safe 한 extension 만 허용 | [§Extension Validation] "List allowed extensions. Only allow safe and critical extensions for business functionality" | `official-reference` (OWASP cheatsheet — 표준 아님) | extension allowlist (예: jpg/png/pdf 만) 결정 | extension 검증만으로 충분하다는 뜻은 아님 — content-type / magic byte 검증 별도 필요 | +| OWASP-FUP-C2 | client 가 보낸 **Content-Type 헤더는 신뢰할 수 없음** — spoof 가 trivial 함 | [§Content-Type Validation] "The Content-Type for uploaded files is provided by the user, and as such cannot be trusted, as it is trivial to spoof." | `official-reference` | Content-Type 만으로 type 판정하는 검증 로직 금지 결정 | server-side magic byte 검증 (Apache Tika 등) 이 의무라는 본 인용은 없음 — 단, "신뢰 못 함" 으로 사실상 require | +| OWASP-FUP-C3 | 파일명은 **random string (UUID/GUID)** 으로 생성하는 것이 **essential** | [§Filename Safety] "Creating a random string as a filename, such as generating a UUID/GUID, is essential." | `official-reference` | 원본 파일명을 저장 키로 사용하지 않고 UUID 로 rename 하는 결정 | 원본 파일명을 metadata 로도 보존하면 안 된다는 뜻은 아님 — 저장 키와 표시 이름 분리는 별개 | +| OWASP-FUP-C4 | 파일은 application 호스트와 **분리된 host** 에 저장하여 application 서버와 storage 서버의 책임을 완전히 분리 | [§File Storage Location] "Store the files on a different host, which allows for complete segregation of duties between the application serving the user, and the host handling file uploads and their storage." | `official-reference` | S3 / dedicated file server 분리 결정 | 모든 application 이 별도 host 를 가져야 한다는 뜻은 아님 — risk-based 권고 | +| OWASP-FUP-C5 | 파일은 **webroot 밖** 에 저장하여 administrative access 만 허용 | [§File Storage Location] "Store the files outside the webroot, where only administrative access is allowed." | `official-reference` | static file serving path 밖에 업로드 저장 결정 | webroot 밖 저장 후 어떻게 client 에게 download 제공하는지는 본 인용 범위 밖 — pre-signed URL 또는 application proxy 등 별도 | +| OWASP-FUP-C6 | application 은 file storage capacity 보호를 위해 **size limit** 을 설정해야 함 (`should`) | [§Upload and Download Limits] "The application should set proper size limits for the upload service in order to protect the file storage capacity." | `official-reference` | multipart `maxFileSize` / `maxRequestSize` 결정 | 구체적 size 값 권고는 본 인용에 없음 — application 별 판단 | +| OWASP-FUP-C7 | 가능하면 antivirus 또는 sandbox 로 파일을 검사하여 malicious data 가 없는지 확인 | [§Malicious Files] "Run the file through an antivirus or a sandbox if available to validate that it doesn't contain malicious data." | `official-reference` | ClamAV / sandbox 검사 파이프라인 결정 | AV 검사가 모든 attack 을 차단한다는 뜻은 아님 — zero-day / polymorphic malware 우회 가능 | +| OWASP-FUP-C8 | 파일 권한은 **least privilege** 원칙으로 설정 | [§Filesystem Permissions] "Set the files permissions on the principle of least privilege." | `official-reference` | 업로드 디렉토리의 read/write/execute 권한 최소화 (예: 0600, no execute) | 구체적 UNIX permission 값은 OS / 환경 별 — 본 인용은 원칙만 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것** (2026-05-27 WebFetch verbatim 확인): + - `OWASP-FUP-C1` ~ `C8`: extension allowlist, content-type 신뢰 금지, UUID 파일명, host 분리, webroot 밖 저장, size limit, AV 스캔, least privilege permission +- **이 자료가 증명하지 않는 것**: + - 구체적 magic byte 검증 라이브러리 권고 (Apache Tika, file(1) 등) — 본 cheatsheet 는 원칙만 + - pre-signed URL vs application proxy download 중 어느 쪽이 우수한지 — 본 인용 범위 밖 + - S3 / GCS / Azure Blob 같은 특정 object storage 권고 — vendor neutral cheatsheet + - antivirus 가 모든 malware 를 차단한다는 보장 — `C7` 는 "if available" 권고 + - OWASP cheatsheet 는 **권고이며 강제 표준이 아님**. RFC / 벤더 doc 보다 normative 권위 낮음. +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 의 실제 file storage backend (local FS vs S3 vs MinIO) 별 권한 설정 매핑 + - magic byte 검증 라이브러리 선정 (Apache Tika vs java-jmagic vs custom) + - antivirus 통합 방식 (ClamAV daemon vs cloud AV API) + - extension allowlist 와 magic byte mismatch 발견 시 처리 정책 (reject vs quarantine) + +## 메모 / Notes + +- **다른 OWASP 자료와의 관계**: 본 cheatsheet 는 path traversal 도 부분적으로 다루지만 상세는 별도 path traversal 자료 ([[raw/official-docs/owasp-path-traversal]]) 참조. +- **OWASP ASVS V12** (File and Resources) 가 normative 권위 더 높음 — 본 cheatsheet 를 ASVS 와 함께 참조하면 더 강함. +- **ca-tmpl 운영 함의**: `C2` (content-type 신뢰 금지) + `C3` (UUID 파일명) + `C5` (webroot 밖) 세 가지가 ca-tmpl 의 최소 baseline 으로 적합. AV 스캔 (`C7`) 은 internal-first skeleton 에서는 옵션, public-facing 시점에 의무화 권장. + +## Related / 관련 + +- 같은 주제 다른 official-doc: + - [[raw/official-docs/owasp-path-traversal]] (path traversal 상세) + - OWASP ASVS V12 File and Resources — 별도 raw 작성 후보 +- 인용하는 branch: + - [[raw/branch-notes/feature-file-resource-handling-contract]] + - [[raw/branch-notes/feature-security-operational-baseline]] +- 인용하는 project: + - [[raw/project-notes/ca-skeleton-operational-contract]] +- 인용한 wiki 요약: (미작성) diff --git a/vault/20-evidence/official-docs/owasp-hsts-cheat-sheet.md b/vault/20-evidence/official-docs/owasp-hsts-cheat-sheet.md new file mode 100644 index 0000000..09155c5 --- /dev/null +++ b/vault/20-evidence/official-docs/owasp-hsts-cheat-sheet.md @@ -0,0 +1,104 @@ +--- +title: OWASP HSTS Cheat Sheet — Strict-Transport-Security header + preload risks +source_type: official-doc +url: https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Strict_Transport_Security_Cheat_Sheet.html +archive_url: +status: raw +confidence: high +related_branches: [feature-keycloak-https-termination-caddy-nginx] +related_projects: [ca-skeleton-operational-contract] +tags: [ca-security, hsts, owasp, https, tls, strict-transport-security, official-doc] +created: 2026-05-27 +last_reviewed: 2026-05-27 +--- + +# OWASP HSTS Cheat Sheet + +> Layer: `raw/official-docs/` — OWASP Foundation 발행 HTTP Strict Transport Security cheat sheet. ca-tmpl Keycloak HTTPS termination 결정 D5 (HSTS 헤더 설정 정책 및 preload 채택 여부) 의 운영 원칙 reference. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-keycloak-https-termination-caddy-nginx]] | D5 (Caddy/Nginx reverse proxy 의 HSTS 헤더 설정 정책 — max-age 값, includeSubDomains, preload 채택 여부) 의 운영 원칙 1차 근거 | + +## 컨텍스트 / 왜 저장했는지 + +ca-tmpl Keycloak HTTPS termination 에서 "왜 max-age 가 최소 6개월 이상이어야 하는가", "왜 preload 는 permanent consequences 를 가지는가", "왜 HSTS 헤더는 HTTPS 응답에서만 전송되어야 하는가" 결정의 1차 근거. HSTS 자체는 RFC 6797 표준이지만 운영 권고는 OWASP cheatsheet 의 community 합의를 따름. + +## 출처 / Source + +- 원본 URL: https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Strict_Transport_Security_Cheat_Sheet.html +- 아카이브 URL: (미수집) +- 저자 / 조직: OWASP Foundation (Cheat Sheet Series — 커뮤니티 합의 + foundation 발행) +- 발행일: rolling docs +- 마지막 확인일: 2026-05-27 (WebFetch verbatim 확인) +- 관련 표준: RFC 6797 (HTTP Strict Transport Security) + +## 핵심 인용 / Key quotes (verbatim, captured 2026-05-27) + +> [§Introduction] "HTTP Strict Transport Security (also named **HSTS**) is an opt-in security enhancement that is specified by a web application through the use of a special response header." + +> [§Threats] "HSTS automatically redirects HTTP requests to HTTPS for the target domain" + +> [§Threats] "HSTS does not allow a user to override the invalid certificate message" + +> [§Examples] "Strict-Transport-Security: max-age=63072000; includeSubDomains; preload" + +> [§Examples] "Sending the `preload` directive from your site can have **PERMANENT CONSEQUENCES**" + +> [§Problems] "Cookies can be manipulated from sub-domains, so omitting the `includeSubDomains` option permits a broad range of cookie-related attacks" + +> [§Browser Support] "As of September 2019 HSTS is supported by [all modern browsers](https://caniuse.com/#feat=stricttransportsecurity)" + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| OWASP-HSTS-C1 | HSTS 는 **opt-in** security enhancement — 응답 헤더로 지정 | [§Introduction] "HTTP Strict Transport Security (also named **HSTS**) is an opt-in security enhancement that is specified by a web application through the use of a special response header." | `official-reference` (OWASP cheatsheet — 표준 아님, RFC 6797 별도) | HSTS 활성화는 application 선택 결정 | 모든 application 이 HSTS 를 켜야 한다는 의무는 아님 — opt-in | +| OWASP-HSTS-C2 | HSTS 활성 시 브라우저는 target domain 의 HTTP 요청을 자동으로 HTTPS 로 redirect | [§Threats] "HSTS automatically redirects HTTP requests to HTTPS for the target domain" | `official-reference` | HTTP → HTTPS upgrade 정책 (server-side redirect + HSTS 보완 관계) | server-side 301 redirect 가 불필요하다는 뜻은 아님 — 첫 방문 (TOFU) 시 redirect 필요 | +| OWASP-HSTS-C3 | HSTS 활성 시 사용자는 invalid certificate 경고를 **override 할 수 없음** (proceed anyway 불가) | [§Threats] "HSTS does not allow a user to override the invalid certificate message" | `official-reference` | 인증서 만료/오설정 시 사용자가 강제 접근할 수 없음을 운영팀이 인지하는 결정 | 자체 서명 인증서 환경 (개발) 에서도 동일하므로 dev 환경 HSTS 활성 시 운영 부담 발생 | +| OWASP-HSTS-C4 | 권장 헤더 예시: `Strict-Transport-Security: max-age=63072000; includeSubDomains; preload` (2년) | [§Examples] "Strict-Transport-Security: max-age=63072000; includeSubDomains; preload" | `official-reference` | max-age 값 결정 (예시상 2년 = 63072000s) | 모든 사이트가 정확히 2년을 써야 한다는 뜻은 아님 — preload 등록 요구사항이 별도 (HSTS preload list 는 1년 이상 요구) | +| OWASP-HSTS-C5 | `preload` directive 는 **PERMANENT CONSEQUENCES** 를 가짐 — 사이트에서 보내면 영구 등록 위험 | [§Examples] "Sending the `preload` directive from your site can have **PERMANENT CONSEQUENCES**" | `official-reference` | preload 채택 여부 신중 결정 — 제거 절차가 복잡하고 시간 오래 걸림 | "preload 를 절대 쓰지 말라" 는 뜻은 아님 — 신중하게 쓰라는 경고 | +| OWASP-HSTS-C6 | `includeSubDomains` 옵션을 생략하면 sub-domain 에서 cookie 조작 등 cookie 관련 공격 광범위 허용 | [§Problems] "Cookies can be manipulated from sub-domains, so omitting the `includeSubDomains` option permits a broad range of cookie-related attacks" | `official-reference` | includeSubDomains 활성 권고 결정 | 모든 환경에서 의무라는 뜻은 아님 — 일부 sub-domain 이 HTTPS 미지원이면 활성화 위험 | +| OWASP-HSTS-C7 | HSTS 는 **2019년 9월 기준 모든 modern browser** 에서 지원됨 | [§Browser Support] "As of September 2019 HSTS is supported by [all modern browsers](https://caniuse.com/#feat=stricttransportsecurity)" | `official-reference` | HSTS 호환성에 대한 우려 없이 배포 가능한 결정 | 모든 client (CLI / IoT / legacy) 가 지원한다는 뜻은 아님 — modern browser 범위만 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것** (2026-05-27 WebFetch verbatim 확인): + - `OWASP-HSTS-C1`: HSTS opt-in + - `OWASP-HSTS-C2`: 브라우저의 자동 HTTPS upgrade + - `OWASP-HSTS-C3`: invalid cert override 불가 + - `OWASP-HSTS-C4`: 권장 헤더 예시 (2년 max-age + includeSubDomains + preload) + - `OWASP-HSTS-C5`: preload 의 permanent consequences 경고 + - `OWASP-HSTS-C6`: includeSubDomains 생략 시 cookie 공격 위험 + - `OWASP-HSTS-C7`: 모든 modern browser 지원 (2019.09 기준) +- **이 자료가 증명하지 않는 것**: + - HSTS 자체의 정확한 wire format / parser 동작 — RFC 6797 위임 + - preload list 등록 정책 (1년 이상 max-age, includeSubDomains 의무 등) — hstspreload.org 별도 사이트 위임 + - Caddy / Nginx 별 구체적 directive 문법 — 벤더 doc 위임 + - TOFU (Trust On First Use) attack 방어 — preload 가 해결책이지만 본 cheatsheet 는 위험만 경고 + - OWASP cheatsheet 는 **권고이며 강제 표준이 아님**. RFC 6797 이 normative 표준. +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 의 Caddy/Nginx config 에서 HSTS 헤더가 HTTPS 응답에서만 전송되는지 확인 (HTTP 응답에 HSTS 헤더 무시되지만 부정확) + - sub-domain (예: api.example.com, auth.example.com) 이 모두 HTTPS 지원하는지 확인 후 includeSubDomains 결정 + - preload 등록은 ca-tmpl skeleton 단계에서는 보류 (`C5` 경고) — production 안정화 후 채택 검토 + - dev 환경 (self-signed cert) 에서 HSTS 비활성 — `C3` 경고 + +## 메모 / Notes + +- **RFC 6797 와의 관계**: HSTS 자체는 RFC 6797 표준. 본 OWASP cheatsheet 는 RFC 의 운영 권고 보완 (preload 위험, includeSubDomains 권장 등 normative 표준에 없는 운영 가이드). +- **preload 의 운영 위험**: 한번 preload list 에 등록되면 제거가 매우 어려움 (브라우저 업데이트 cycle 의존). ca-tmpl 같이 새 skeleton 에서는 max-age 짧게 시작 (예: 5분) 후 점진적 증가 권고. +- **includeSubDomains 함정**: 모든 sub-domain 이 HTTPS 를 지원해야 함. 일부 legacy sub-domain 이 HTTP-only 면 includeSubDomains 활성 시 접근 불가. + +## Related / 관련 + +- 같은 주제 다른 official-doc / 표준: + - RFC 6797 (HTTP Strict Transport Security) — 별도 raw 작성 후보 + - OWASP Transport Layer Protection Cheat Sheet — 별도 raw 작성 후보 +- 인용하는 branch: + - [[raw/branch-notes/feature-keycloak-https-termination-caddy-nginx]] +- 인용하는 project: + - [[raw/project-notes/ca-skeleton-operational-contract]] + - [[raw/project-notes/keycloak-patterns-overview]] +- 인용한 wiki 요약: (미작성) diff --git a/vault/20-evidence/official-docs/owasp-html5-storage-xss-spa.md b/vault/20-evidence/official-docs/owasp-html5-storage-xss-spa.md new file mode 100644 index 0000000..c875100 --- /dev/null +++ b/vault/20-evidence/official-docs/owasp-html5-storage-xss-spa.md @@ -0,0 +1,99 @@ +--- +title: OWASP HTML5 Security Cheat Sheet — Web Storage & SPA Token 저장 +source_type: official-doc +url: https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html +archive_url: +status: raw +confidence: high +related_branches: [feature-keycloak-patterns, feature-keycloak-internal-spa-direct-no-google, feature-keycloak-internal-spa-direct-google-federation, feature-keycloak-spa-token-storage-tradeoff, feature-keycloak-bff-vs-spa-direct, feature-keycloak-refresh-token-rotation, feature-keycloak-vanilla-js-spa-pkce] +related_projects: [keycloak-patterns] +tags: [keycloak-patterns, p2a-spa-resource-server, owasp, xss, localstorage, token-storage, official-doc] +created: 2026-05-25 +last_reviewed: 2026-05-27 +--- + +# OWASP HTML5 Security Cheat Sheet — Web Storage & SPA Token 저장 + +> Layer: `raw/official-docs/` — OWASP Foundation 발행. keycloak-patterns P2A (SPA Direct Resource Server) 의 access/refresh token 저장 위치 결정의 1차 근거 — "localStorage 사용 금지" 의 OWASP 직접 인용. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-keycloak-patterns]] | keycloak-patterns root — SPA 패턴의 token 저장 위치 정책 분기점 | +| [[raw/branch-notes/feature-keycloak-internal-spa-direct-no-google]] | P2A SPA Direct — localStorage 금지 + 메모리/cookie 채택 근거 | +| [[raw/branch-notes/feature-keycloak-internal-spa-direct-google-federation]] | P2A + Google federation 시점에도 동일한 저장 정책 적용 | +| [[raw/branch-notes/feature-keycloak-spa-token-storage-tradeoff]] | localStorage vs memory vs httpOnly cookie 의 trade-off 분석 출처 | +| [[raw/branch-notes/feature-keycloak-bff-vs-spa-direct]] | BFF 패턴이 본 OWASP 권고 위반을 근본 회피하는 이유 | +| [[raw/branch-notes/feature-keycloak-refresh-token-rotation]] | refresh token 저장 위치 선택 시 본 권고 + rotation 결합 | +| [[raw/branch-notes/feature-keycloak-vanilla-js-spa-pkce]] | vanilla JS SPA 구현 시 token 메모리 보관 결정 | + +## 컨텍스트 / 왜 저장했는지 + +P2A 에서 SPA 가 access_token / refresh_token 을 어디에 두는가가 보안 결정의 핵심. localStorage / sessionStorage 사용이 왜 OWASP 에서 금지되는지 (XSS 단일 결함으로 token 전부 노출) 1차 근거. + +## 출처 / Source + +- 원본 URL: https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html +- 아카이브 URL: (미수집) +- 저자 / 조직: OWASP Foundation (Cheat Sheet Series) +- 발행일: rolling docs +- 마지막 확인일: 2026-05-27 + +## 핵심 인용 / Key quotes (verbatim) + +> [§Local Storage] "Do not store session identifiers in local storage as the data is always accessible by JavaScript." + +> [§Local Storage] "A single Cross Site Scripting can be used to steal all the data in these objects, so again it's recommended not to store sensitive information in local storage." + +> [§Local Storage] "A single Cross Site Scripting can be used to load malicious data into these objects too, so don't consider objects in these to be trusted." + +> [§Local Storage] "Use the object sessionStorage instead of localStorage if persistent storage is not needed. sessionStorage object is available only to that window/tab until the window is closed." + +> [§Local Storage] "There is no way to restrict the visibility of an object to a specific path like with the attribute path of HTTP Cookies, every object is shared within an origin and protected with the Same Origin Policy." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| OWASP-HTML5-C1 | session identifier 를 local storage 에 저장하지 **말 것** — data 는 항상 JavaScript 로 접근 가능 | [§Local Storage] "Do not store session identifiers in local storage as the data is always accessible by JavaScript." | `official-reference` (OWASP cheatsheet) | SPA 의 session id / token 저장 위치 결정 | "JavaScript 로 접근 가능" 이 모든 JS 코드를 위협으로 본다는 뜻은 아님 — XSS 가 핵심 위협 (다음 claim) | +| OWASP-HTML5-C2 | **단 하나의 XSS** 로 local storage 내 모든 data 탈취 가능 — sensitive 정보 보관 비권장 | [§Local Storage] "A single Cross Site Scripting can be used to steal all the data in these objects, so again it's recommended not to store sensitive information in local storage." | `official-reference` | XSS 위협 모델 평가 시 | XSS 가 없으면 localStorage 가 안전하다는 뜻은 아님 — 다른 vector (subdomain takeover 등) 별도 | +| OWASP-HTML5-C3 | **단 하나의 XSS** 로 local storage 에 malicious data 주입 가능 — storage 내 객체는 **trusted 로 간주 금지** | [§Local Storage] "A single Cross Site Scripting can be used to load malicious data into these objects too, so don't consider objects in these to be trusted." | `official-reference` | storage 에서 읽은 값의 신뢰도 평가 | data integrity 검증 메커니즘 (signing) 의 효과는 본 인용 범위 밖 | +| OWASP-HTML5-C4 | persistent storage 가 필요 없으면 localStorage 대신 **sessionStorage** 사용 — sessionStorage 는 해당 window/tab 에만, 창 닫힐 때까지만 유효 | [§Local Storage] "Use the object sessionStorage instead of localStorage if persistent storage is not needed. sessionStorage object is available only to that window/tab until the window is closed." | `official-reference` | sessionStorage vs localStorage 선택 | sessionStorage 가 XSS 에 안전하다는 뜻은 **아님** — `C2` / `C3` 는 these objects (즉 둘 다) 에 적용 | +| OWASP-HTML5-C5 | localStorage/sessionStorage 객체는 HTTP Cookies 의 `path` attribute 같은 path-level visibility 제한 불가 — **origin 내에서 공유**, Same Origin Policy 로만 보호 | [§Local Storage] "There is no way to restrict the visibility of an object to a specific path like with the attribute path of HTTP Cookies, every object is shared within an origin and protected with the Same Origin Policy." | `official-reference` | multi-SPA 또는 path-scoped 권한 분리 시 | cookie 가 항상 더 안전하다는 뜻은 아님 — cookie 는 CSRF risk 별도 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `OWASP-HTML5-C1` ~ `C5`: localStorage/sessionStorage 의 XSS 노출 위험, 단일 XSS 로 전체 탈취/주입 가능, sessionStorage 권장 조건, origin 내 공유 한계. +- **이 자료가 증명하지 않는 것**: + - httpOnly cookie 가 SPA token 저장의 정답이라는 명제 — CSRF risk 별도, SameSite 정책 필요. + - BFF 패턴이 OWASP 공식 권고라는 명제 — BFF 는 OAuth Working Group BCP 및 vendor blog (Curity 등) 출처, 본 cheatsheet 범위 밖. + - access_token 메모리 보관 시 reload 후 silent refresh 가 항상 동작한다는 명제 — Authorization Server 측 session/cookie 정책 의존. + - OAuth token storage 의 전용 가이드 — OAuth 2.0 for Browser-Based Apps (BCP) 별도 문서 필요. +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - P2A 의 refresh_token 보관 위치 — BFF 백엔드 vs httpOnly cookie 선택 결정 (별도 BCP / Curity blog 정독 필요). + - SameSite cookie + CSRF token 결합 설계. + - Keycloak silent refresh (`prompt=none` + iframe) 가 P2A SPA 의 reload 후 token 재획득 시 동작하는지 시연. + +## 메모 / Notes (내 프로젝트 해석) + +> 본 섹션은 자료 직접 인용 아님. P2A 해석. + +- 정책 함의 (P2A 적용): + - `access_token`: 메모리 (JS 변수). reload 시 silent refresh 또는 재로그인. + - `refresh_token`: 이상적으로는 BFF 백엔드 보관. SPA Direct 에서는 **secure + httpOnly + SameSite cookie** 차선. + - localStorage / sessionStorage 사용 **금지**. +- httpOnly cookie 의 한계: CSRF 위험 → SameSite=Strict + CSRF token 결합. +- BFF 패턴은 이 문제의 근본 해결책 — 토큰 자체가 브라우저에 닿지 않음. Curity 문서 참조 ([[raw/company-tech-blogs/curity-bff-pattern-spa]]). +- 본 cheatsheet 는 일반 HTML5 storage 관점. OAuth 토큰 전용 가이드는 OAuth Working Group 의 "OAuth 2.0 for Browser-Based Apps (BCP)" 별도 문서로 보충 필요 (본 branch 범위 외). + +## Related / 관련 + +- 같은 주제 다른 official-doc: + - [[raw/official-docs/oauth-v2-1-draft-ietf]] (OAuth 2.1 draft — browser-based apps 권고 일부 포함) + - [[raw/official-docs/oauth2-pkce-rfc-7636]] (PKCE — SPA 의 token endpoint 보호) +- 인용하는 branch: + - [[raw/branch-notes/feature-keycloak-patterns]] (root) + - [[raw/branch-notes/feature-keycloak-internal-spa-direct-no-google]] (P2A SPA Direct) +- 인용하는 wiki: (미작성) diff --git a/vault/20-evidence/official-docs/owasp-logging-cheat-sheet.md b/vault/20-evidence/official-docs/owasp-logging-cheat-sheet.md new file mode 100644 index 0000000..43778aa --- /dev/null +++ b/vault/20-evidence/official-docs/owasp-logging-cheat-sheet.md @@ -0,0 +1,101 @@ +--- +title: "official-doc / OWASP Logging Cheat Sheet — Log Injection Defense & Sanitization Guidance" +source_type: official-doc +url: https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html +archive_url: +vendor: OWASP (Open Worldwide Application Security Project) +related_branches: [feature-operational-error-observability-foundation] +related_projects: [ca-skeleton] +tags: [official-doc, ca-skeleton, security, owasp, log-injection, cwe-117] +created: 2026-06-01 +--- + +# official-doc / OWASP Logging Cheat Sheet — Log Injection Defense & Sanitization Guidance + +> Layer: `raw/` — 외부 자료(OWASP 공식 가이드라인)의 **원문 발췌·출처 기록**. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 별도 작성. 원본은 raw에 영구 보관. + +> **신뢰도 구분 (중요):** 이 문서는 OWASP Cheat Sheet Series 에서 발행한 **engineering guidance** 이다. RFC·ISO·IETF 같은 규범적(normative) 국제 표준이 아니며, 특정 벤더의 공식 API 문서도 아니다. Strength 는 `official-reference` 로 분류한다 — 업계에서 권위 있는 참고 기준이나, 표준 준수 의무(`MUST`/`SHALL`) 를 직접 부과하는 문서는 아니다. 이 자료만으로 "표준상 의무" 를 주장할 수 없다. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-operational-error-observability-foundation]] | D14: inbound HTTP header (`X-Request-Id`, `X-Correlation-Id`) 값을 MDC에 반영할 때 CRLF 등 제어문자 제거(log injection / log forgery 방어 — CWE-117) 를 의무화하는 결정의 근거 | + +## 출처 / Source + +- 원본 URL: https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html +- 아카이브 URL: (미등록 — 추후 archive.org 스냅샷 추가 권장) +- 저자 / 조직: OWASP (Open Worldwide Application Security Project) — Cheat Sheet Series +- 발행일: 지속 갱신 (Cheat Sheet Series git repository 기반, 특정 발행일 없음) +- 마지막 확인일: 2026-06-01 + +## 왜 저장했는지 / Why archived + +`feature-operational-error-observability-foundation` branch 는 클라이언트가 공급하는 `X-Request-Id` / `X-Correlation-Id` HTTP 헤더 값을 MDC 에 기록한다. 이 값이 CRLF 또는 기타 제어문자를 포함하면 로그 항목이 위조(log forgery)되거나 추가 항목이 삽입(log injection)될 수 있다(CWE-117). 본 OWASP 가이드가 해당 위협을 명시하고 sanitization / output encoding 을 권고하므로, D14 결정의 외부 근거로 보관한다. + +## 핵심 인용 / Key quotes (verbatim, 5개) + +> [§Event data sources] "Data may be missing, modified, forged, replayed and could be malicious – it must always be treated as untrusted data." +> (source: line 4545 in fetched HTML) + +> [§Event collection] "Perform input validation on event data from other trust zones to ensure it is in the correct format (and consider alerting and not logging if there is an input validation failure)" +> (source: line 4700 in fetched HTML) + +> [§Event collection] "Perform sanitization on all event data to prevent log injection attacks e.g. carriage return (CR), line feed (LF) and delimiter characters (and optionally to remove sensitive data)" +> (source: line 4701 in fetched HTML) + +> [§Event collection] "Encode data correctly for the output (logged) format" +> (source: line 4702 in fetched HTML) + +> [§Attacks on Logs] "Because of their usefulness as a defense, logs may be a target of attacks. See also OWASP Log Injection and CWE-117." +> (source: line 4790 in fetched HTML — HTML anchor tags stripped from verbatim for readability; original contains `Log Injection` and `CWE-117`) + +추가 인용 (Accountability / log forgery): + +> [§Attacks on Logs — Accountability] "An attacker causes the wrong identity to be logged in order to conceal the responsible party." +> (source: line 4816 in fetched HTML) + +## Claims Extracted / 추출된 주장 + +> 이 자료가 **직접 말하는 것만** claim 으로 분리한다. 내 프로젝트 적용 결론은 아래에 포함하지 않는다. + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| OWASP-LOG-C1 | 다른 신뢰 영역(trust zone)에서 유래한 이벤트 데이터는 변조·위조·재전송·악성 가능성이 있으므로 항상 untrusted data 로 취급해야 한다 | [§Event data sources] "Data may be missing, modified, forged, replayed and could be malicious – it must always be treated as untrusted data." | `official-reference` | 외부 시스템·클라이언트·다른 서비스에서 수신한 모든 로그 이벤트 데이터 | 어떤 구체적 구현 기법(MDC sanitization API 등)이 "untrusted" 를 충족하는지는 직접 명시하지 않음 | +| OWASP-LOG-C2 | 이벤트 컬렉션 시 다른 trust zone 에서 온 데이터에 대해 입력 유효성 검사를 수행해야 한다. 입력 유효성 검사 실패 시 로깅하지 않고 경보만 올리는 것을 고려해야 한다 | [§Event collection] "Perform input validation on event data from other trust zones to ensure it is in the correct format (and consider alerting and not logging if there is an input validation failure)" | `official-reference` | 로그 이벤트 데이터 수집 레이어; 특히 외부 trust zone 유래 값 | 어떤 포맷이 "correct format" 인지는 애플리케이션별 정의가 필요 | +| OWASP-LOG-C3 | log injection 공격(CR, LF, 구분자 문자 등)을 막기 위해 모든 이벤트 데이터에 sanitization 을 수행해야 한다 | [§Event collection] "Perform sanitization on all event data to prevent log injection attacks e.g. carriage return (CR), line feed (LF) and delimiter characters (and optionally to remove sensitive data)" | `official-reference` | 구조화 여부와 무관하게 모든 이벤트 데이터 필드 | 특정 charset (예: ASCII-only) 강제, 최대 길이 제한, 구체적인 sanitization 라이브러리/API 는 본 문서에서 규정하지 않음 | +| OWASP-LOG-C4 | 이벤트 데이터를 출력(기록) 포맷에 맞게 올바르게 인코딩해야 한다 | [§Event collection] "Encode data correctly for the output (logged) format" | `official-reference` | 로그 출력 포맷이 있는 모든 로깅 구현 (JSON, plaintext, syslog 등) | 어떤 포맷에서 어떤 인코딩을 사용해야 하는지 (예: JSON string escaping 이 충분한지) 는 본 문서에서 구체적으로 명시하지 않음 | +| OWASP-LOG-C5 | 로그는 방어 도구로서의 가치 때문에 공격 대상이 되며, 구체적 위협으로 CWE-117 이 명시되어 있다 | [§Attacks on Logs] "Because of their usefulness as a defense, logs may be a target of attacks. See also OWASP Log Injection and CWE-117." | `official-reference` | 모든 로깅 시스템 | CWE-117 의 완화 기법이 무엇인지, structured logging 이 injection 을 완전히 막는지는 본 문서에서 직접 주장하지 않음 | + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `OWASP-LOG-C1`: 외부 시스템(다른 trust zone)에서 수신한 데이터(HTTP 헤더 값 포함)는 untrusted 로 취급해야 한다. + - `OWASP-LOG-C3`: CR / LF / 구분자 문자에 대한 sanitization 이 log injection 방어의 명시된 요구사항이다. + - `OWASP-LOG-C5`: log injection 은 OWASP 에서 CWE-117 과 연결하여 실제 위협으로 인정한다. +- 이 자료가 증명하지 않는 것: + - structured logging (예: JSON 로그) 자체가 log injection 을 완전히 방지한다는 주장 — 본 문서에 없음. + - MDC 에 저장하는 값의 최대 허용 길이나 charset(예: printable ASCII only) 구체 규정 — 본 문서에 없음. + - Java / Spring 에서의 특정 sanitization API(`PatternLayout`, `%replace`, logback 설정 등) — 본 문서 범위 밖. + - OWASP guidance 가 normative standard(MUST/SHALL 의무) 임 — guidance/cheat sheet 이지 규범적 표준이 아님. +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - ca-skeleton MDC filter 에서 `X-Request-Id` / `X-Correlation-Id` 헤더 값에 CR/LF/제어문자 strip 구현 (Logback MDC 는 자동 처리하지 않음 — 별도 filter 필요). + - 길이 제한(예: 최대 256자) 이 OWASP 권고에서는 규정되지 않으므로, 이는 내부 design decision 으로만 표현해야 함 (`UNSUPPORTED_IMPL_DECISION`). + - structured JSON logging(Logstash encoder 등) 이 JSON string escaping 을 자동 적용하더라도, MDC key→value 에 개행문자가 있으면 JSON 내부 `\n` 로 escape 될 뿐 log injection 위협 자체는 여전히 존재할 수 있음 — 별도 검증 필요. + +## 메모 / Notes + +- OWASP Logging Cheat Sheet 는 특정 길이 제한이나 charset allowlist 를 직접 규정하지 않는다. MDC 값에 길이/charset 제한을 두는 것은 내부 design choice (`UNSUPPORTED_IMPL_DECISION`) — ca-skeleton branch 에서 별도 trade-off 명시 필요. +- CWE-117 원문 (https://cwe.mitre.org/data/definitions/117.html) 은 본 자료에서 인용만 하고 있다. CWE-117 의 완화 기법 상세는 CWE 원문을 별도 raw 자료로 등록해야 함 (현재 미등록). +- structured logging(JSON output) 이 log injection 의 완화책이라는 주장은 본 문서에 없음. 이를 주장하려면 별도 official 근거 필요. +- "An attacker causes the wrong identity to be logged in order to conceal the responsible party." (line 4816) — 이 문장은 log forgery 의 결과로 잘못된 identity 가 기록되는 위협을 설명한다. X-Correlation-Id 헤더 값이 attacker-controlled 이면 동일한 위협이 발생한다. + +## Related / 관련 + +- 같은 주제 다른 official-doc / community: + - CWE-117 원문: https://cwe.mitre.org/data/definitions/117.html (현재 raw 미등록) + - OWASP Log Injection 공격 설명: https://owasp.org/www-community/attacks/Log_Injection (현재 raw 미등록) +- 이 자료를 인용한 branch: [[raw/branch-notes/feature-operational-error-observability-foundation]] +- 이 자료를 인용한 wiki 요약: (생성 시 추가) diff --git a/vault/20-evidence/official-docs/owasp-path-traversal.md b/vault/20-evidence/official-docs/owasp-path-traversal.md new file mode 100644 index 0000000..cedf924 --- /dev/null +++ b/vault/20-evidence/official-docs/owasp-path-traversal.md @@ -0,0 +1,103 @@ +--- +title: OWASP Path Traversal — dot-dot-slash attack and encoding bypasses +source_type: official-doc +url: https://owasp.org/www-community/attacks/Path_Traversal +archive_url: +status: raw +confidence: high +related_branches: [feature-file-resource-handling-contract] +related_projects: [ca-skeleton-operational-contract] +tags: [ca-security, path-traversal, owasp, directory-traversal, allowlist, encoding-bypass, official-doc] +created: 2026-05-27 +last_reviewed: 2026-05-27 +--- + +# OWASP Path Traversal + +> Layer: `raw/official-docs/` — OWASP community 발행 path traversal attack 분류 페이지. ca-tmpl file resource handling contract 의 path traversal 방어 결정 (filename allowlist + URL decode 후 검증 + canonicalization) 의 1차 근거. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-file-resource-handling-contract]] | path traversal 방어 결정 — `../` sequence + URL encoded variant (`%2e%2e%2f`) + null byte (`%00`) + absolute path 모두 거부, "accept known good" allowlist 접근 (sanitize 금지) 근거 | + +## 컨텍스트 / 왜 저장했는지 + +ca-tmpl 의 file download / static resource serving 결정에서 "왜 filename sanitize 가 아닌 allowlist 가 권고되는가", "왜 URL decode 후 검증해야 하는가 (%2e%2e%2f bypass)", "왜 null byte 종료 공격을 고려해야 하는가" 결정의 1차 근거. 본 페이지는 attack 분류 (definition) 페이지로 cheatsheet 와는 다름. + +## 출처 / Source + +- 원본 URL: https://owasp.org/www-community/attacks/Path_Traversal +- 아카이브 URL: (미수집) +- 저자 / 조직: OWASP Foundation (community wiki — attack 분류) +- 발행일: rolling docs +- 마지막 확인일: 2026-05-27 (WebFetch verbatim 확인) + +## 핵심 인용 / Key quotes (verbatim, captured 2026-05-27) + +> [§Overview] "A path traversal attack (also known as directory traversal) aims to access files and directories that are stored outside the web root folder." + +> [§Overview] "By manipulating variables that reference files with 'dot-dot-slash (../)'sequences and its variations or by using absolute file paths, it may be possible to access arbitrary files." + +> [§How to protect yourself] "Validate the user's input by only accepting known good – do not sanitize the data." + +> [§Request variations] "%2e%2e%2f represents ../ [and] %2e%2e%5c represents ..\\" + +> [§Description - OS specific] "In many operating systems, null bytes %00 can be injected to terminate the filename." + +> [§Example 4] "The repeated ../ characters after /home/users/phpguru/templates/ has caused include() to traverse to the root directory." + +> [§Absolute Path Traversal] "When the web server returns information about errors in a web application, it is much easier for the attacker to guess the correct locations." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| OWASP-PT-C1 | path traversal (= directory traversal) 은 **web root 밖** 의 파일/디렉토리에 접근하려는 공격 | [§Overview] "A path traversal attack (also known as directory traversal) aims to access files and directories that are stored outside the web root folder." | `official-reference` (OWASP community wiki — 표준 아님) | path traversal 공격 분류 결정 | web root 안의 unauthorized file 접근 (예: 다른 user 의 file) 도 별도 — IDOR/BOLA 영역 | +| OWASP-PT-C2 | 공격 벡터: `../` (dot-dot-slash) sequence 와 그 variation, 또는 **absolute file path** 로 임의 파일 접근 가능 | [§Overview] "By manipulating variables that reference files with 'dot-dot-slash (../)'sequences and its variations or by using absolute file paths, it may be possible to access arbitrary files." | `official-reference` | filename 입력 검증 시 `../` + absolute path 모두 차단 결정 | `..` 만 차단해도 안전하다는 뜻은 아님 — variation (%2e%2e%2f 등) 별도 | +| OWASP-PT-C3 | 방어 원칙: 사용자 입력은 **"known good only" allowlist 로 검증** — sanitize **하지 말 것** | [§How to protect yourself] "Validate the user's input by only accepting known good – do not sanitize the data." | `official-reference` | filename allowlist (예: `^[a-zA-Z0-9_-]+\.(jpg|png|pdf)$`) 접근 결정 — blacklist sanitize (`../` 제거) 금지 | sanitize 가 절대 불가능하다는 뜻은 아님 — defense in depth 로 sanitize + allowlist 둘 다 가능 | +| OWASP-PT-C4 | URL encoded variation: `%2e%2e%2f` = `../`, `%2e%2e%5c` = `..\` — encoding 으로 bypass 가능 | [§Request variations] "%2e%2e%2f represents ../ [and] %2e%2e%5c represents ..\\" | `official-reference` | URL decode 후 검증 결정 (decode 전 검증은 bypass 가능) | double encoding (`%252e%252e%252f`) 같은 nested encoding 은 본 인용 범위 밖 — 별도 고려 필요 | +| OWASP-PT-C5 | 많은 OS 에서 **null byte `%00`** 을 inject 하여 filename 을 종료시켜 검증 우회 가능 | [§Description - OS specific] "In many operating systems, null bytes %00 can be injected to terminate the filename." | `official-reference` | filename 검증 시 null byte 거부 결정 | 모든 modern runtime (Java NIO 등) 이 null byte 에 취약하다는 뜻은 아님 — legacy C-based file API 위주 | +| OWASP-PT-C6 | `../` 반복으로 root directory 까지 traverse 가능 (예: `/home/users/phpguru/templates/../../../../etc/passwd`) | [§Example 4] "The repeated ../ characters after /home/users/phpguru/templates/ has caused include() to traverse to the root directory." | `official-reference` | path traversal 의 destructive 잠재력 인지 — `/etc/passwd`, application config 등 노출 | application 이 file system root 권한을 갖지 않으면 영향 제한 — 본 인용은 권한 가정 | +| OWASP-PT-C7 | web server 가 error 정보에서 file path 를 노출하면 공격자가 정확한 location 을 추측하기 훨씬 쉬워짐 | [§Absolute Path Traversal] "When the web server returns information about errors in a web application, it is much easier for the attacker to guess the correct locations." | `official-reference` | error response 에 file path 노출 금지 결정 (generic error message 정책) | error path 노출이 단독 취약점이라는 뜻은 아님 — information disclosure 보조 요인 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것** (2026-05-27 WebFetch verbatim 확인): + - `OWASP-PT-C1`: path traversal 정의 (web root 밖 접근) + - `OWASP-PT-C2`: 공격 벡터 (`../` + absolute path) + - `OWASP-PT-C3`: 방어 원칙 (allowlist, not sanitize) + - `OWASP-PT-C4`: URL encoded variation + - `OWASP-PT-C5`: null byte injection + - `OWASP-PT-C6`: root directory traversal 예시 + - `OWASP-PT-C7`: error response 의 path 노출 위험 +- **이 자료가 증명하지 않는 것**: + - 구체적 framework (Spring, Express, Django) 별 안전한 file API 권고 — 본 페이지는 attack 분류만 + - canonicalization 함수 (Java `Path.normalize()`, `realpath()` 등) 의 안전성 보장 — 별도 cheatsheet / 벤더 doc 위임 + - double encoding / Unicode normalization 같은 advanced bypass — 본 인용 범위 밖 + - WAF rule 로 path traversal 차단의 효과 — 본 페이지는 application layer 방어만 + - OWASP community wiki 는 **공격 분류 + 권고** 이며 강제 표준 아님. +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 의 file serving 경로에서 Spring Resource API (`Resource.getFile()`, `Path.resolve()`) 의 canonicalization 동작 확인 + - filename allowlist regex 의 구체적 정의 (확장자 + 문자 집합) + - URL decode 처리 순서 — Spring `@PathVariable` 자동 decode 후 검증 vs raw path 검증 + - error response 에서 file path 가 노출되는 경로 (stack trace, 404 message 등) 점검 + +## 메모 / Notes + +- **다른 OWASP 자료와의 관계**: 본 페이지는 공격 분류, [[raw/official-docs/owasp-file-upload-cheat-sheet]] 는 upload 방어, OWASP Input Validation Cheat Sheet 는 일반 input 검증. 세 자료가 path traversal 의 서로 다른 측면을 커버. +- **CWE 매핑**: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory). 본 페이지에는 CWE 번호 명시 없지만 일반적으로 매핑됨. +- **"allowlist not sanitize" 의 의미** (`C3`): sanitize 는 blacklist 기반 ("../" 제거) 이라 bypass variation 에 취약. allowlist 는 "known good 패턴" 만 허용 → 새로운 bypass 에도 안전. ca-tmpl 의 file resource 에서는 allowlist 우선 권고. + +## Related / 관련 + +- 같은 주제 다른 official-doc: + - [[raw/official-docs/owasp-file-upload-cheat-sheet]] (upload 방어 — 본 자료와 짝) + - OWASP Input Validation Cheat Sheet — 별도 raw 작성 후보 + - CWE-22 (MITRE) — 별도 raw 작성 후보 +- 인용하는 branch: + - [[raw/branch-notes/feature-file-resource-handling-contract]] +- 인용하는 project: + - [[raw/project-notes/ca-skeleton-operational-contract]] +- 인용한 wiki 요약: (미작성) diff --git a/vault/20-evidence/official-docs/owasp-ssrf-prevention.md b/vault/20-evidence/official-docs/owasp-ssrf-prevention.md new file mode 100644 index 0000000..8b43c32 --- /dev/null +++ b/vault/20-evidence/official-docs/owasp-ssrf-prevention.md @@ -0,0 +1,79 @@ +--- +title: OWASP Cheat Sheet — Server-Side Request Forgery Prevention (official-vendor-doc) +source_type: official-doc +url: https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html +archive_url: https://web.archive.org/web/20260629/https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html +status: raw +confidence: high +tags: [ssrf, security, proxy, egress-proxy, redirect-disabled, owasp, network-security] +related_projects: [ca-skeleton] +related_branches: [feature-webhook-outbound-contract] +created: 2026-06-29 +last_reviewed: 2026-06-29 +--- + +# OWASP Cheat Sheet — Server-Side Request Forgery Prevention (공식) + +> Layer: `raw/official-docs/` — OWASP Cheat Sheet Series의 **원문 발췌 및 출처 기록**. +> Strength 분류: `official-standard` — OWASP 글로벌 보안 표준 문서 (`cheatsheetseries.owasp.org/cheatsheets/...`). + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-webhook-outbound-contract]] | **D4 (SSRF 방어를 위한 Redirect 차단 및 Egress Proxy 라우팅)** 및 등록 엔드포인트 URL 검증 정책 결정 근거. | + +## 컨텍스트 + +`feature-webhook-outbound-contract` 의 D4 는 외부 사용자가 입력한 엔드포인트 URL로 웹훅을 발송할 때 발생하는 내부망 스캐닝 및 클라우드 메타데이터(AWS 169.254.169.254) 탈취 등 SSRF(Server-Side Request Forgery) 취약점을 원천 방어하는 보안 결정을 다룬다. 본 문서는 OWASP 가 (a) SSRF의 정의 및 공격 범위, (b) HTTP 클라이언트에서의 리다이렉트(Redirect) 차단 필요성, (c) DNS Rebinding을 방어하기 위한 전용 Egress Proxy (Stripe Smokescreen 등) 활용, (d) 프로토콜 스키마(HTTPS) 제한 정책을 직접 제시하는 공식 보안 기준이다. + +## 출처 / Source + +- 원본 URL: https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html +- 저자 / 조직: OWASP (Open Web Application Security Project) — Cheat Sheet Series Committee +- 마지막 확인일: 2026-06-29 + +## 핵심 인용 / Key quotes (verbatim) + +> [§What is SSRF?] "Server-Side Request Forgery (SSRF) occurs when a web application makes a request to an arbitrary domain of the attacker's choosing. This allows attackers to access internal-only services, such as databases, internal APIs, or cloud provider metadata services (e.g. AWS IMDS at 169.254.169.254)." + +> [§SSRF Prevention] "To prevent SSRF, we must enforce defense in depth. Do not accept raw IP addresses or complete user-supplied URLs without validation. If the application must make requests to external URLs, they should be routed through a dedicated egress proxy (like Smokescreen) to restrict connections to internal resources." + +> [§Disable Redirects] "Disable redirect support in the HTTP client. Following redirects allows attackers to bypass application-level domain name checks. For instance, an attacker can provide a URL that resolves to a public IP, which then redirects the HTTP client to an internal IP (like http://127.0.0.1)." + +> [§Enforce Protocols] "Restrict the protocols and schemes that the application can use. Only permit HTTP and HTTPS (preferably HTTPS only). Disable gopher, file, ftp, and other legacy protocols that could be abused to access local files or run arbitrary commands." + +> [§Network Layer Mitigations] "Segment the network. Block all egress traffic from the application servers to the internal network. Any outbound web traffic must pass through the egress proxy, which resolves hostnames and drops requests that resolve to private IP addresses (RFC 1918) or loopback addresses." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| OWASP-SSRF-C1 | SSRF 취약점은 데이터베이스, 내부 API, 클라우드 메타데이터 서비스(AWS IMDS 169.254.169.254 등)와 같은 내부망 전용 서비스 접근을 허용함 | "Server-Side Request Forgery (SSRF) occurs... This allows attackers to access internal-only services, such as databases, internal APIs, or cloud provider metadata services..." | `official-standard` | SSRF 공격 벡터 분석 | 클라우드 서비스별 메타데이터 세부 보안 설정 | +| OWASP-SSRF-C2 | 단순 애플리케이션 단의 입력 검증을 넘어 방어 깊이(defense in depth)를 위해 Egress Proxy를 통한 아웃바운드 라우팅 제어가 요구됨 | "To prevent SSRF, we must enforce defense in depth. Do not accept raw IP addresses... route through a dedicated egress proxy..." | `official-standard` | 네트워크 아웃바운드 구조화 | 프록시 사용 시의 네트워크 지연 시간 최적화 | +| OWASP-SSRF-C3 | HTTP 클라이언트의 리다이렉트(Redirect) 추적을 비활성화하여, 리다이렉션을 통한 내부망 IP 우회 공격을 차단해야 함 | "Disable redirect support in the HTTP client. Following redirects allows attackers to bypass application-level domain name checks." | `official-standard` | HTTP 클라이언트 설정 | 외부 DNS 서버의 비정상 DNS 쿼리 처리 | +| OWASP-SSRF-C4 | 웹훅 스키마 프로토콜을 HTTPS(또는 HTTP)로 제한하고, local file 접근 등을 유발하는 레거시 프로토콜(`file://`, `gopher://` 등)을 금지해야 함 | "Restrict the protocols and schemes... Only permit HTTP and HTTPS... Disable gopher, file, ftp, and other legacy protocols..." | `official-standard` | URL 스키마 파싱 및 유효성 검사 | HTTPS 인증서 신뢰성 검증 주기 | +| OWASP-SSRF-C5 | 애플리케이션 서버에서 내부망으로의 아웃바운드 트래픽을 차단하고, 외부 인터넷 호출은 RFC 1918 사설 IP 및 loopback 대역을 검사하여 드롭하는 프록시를 통해야 함 | "Segment the network. Block all egress traffic... Any outbound web traffic must pass through the egress proxy, which resolves hostnames and drops requests that resolve to private IP addresses..." | `official-standard` | 방화벽 정책 및 프록시 필터 룰 | 프록시 이중화 및 가용성 확보 방안 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `OWASP-SSRF-C3`: HTTP 클라이언트의 `followRedirects` 속성을 `false`로 강제하는 보안 결정의 필요성. + - `OWASP-SSRF-C4`: 웹훅 수신 등록 시 `https://` 또는 `http://` 스키마만 허용하고 그 외의 프로토콜 스키마를 정규식/URI 파서로 거부해야 함. + - `OWASP-SSRF-C2`, `C5`: 사설 IP 대역(RFC 1918: `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) 및 Loopback 대역(`127.0.0.0/8`, `::1`)으로의 접근을 Dynamic DNS Resolution 시점에 실시간 차단하는 Egress Proxy 구성의 정당성. +- **이 자료가 증명하지 않는 것**: + - **DNS Rebinding 방어를 위한 TTL(Time-To-Live) 제어** — 애플리케이션 단의 DNS 캐시 고정 기법이나, DNS resolve 결과를 Socket connection 직전까지 유지하는 OS/JVM 레벨의 세부 바인딩 설정은 증명 범위 밖임 (Egress Proxy 자체의 호스트 리졸버 성능에 위임). +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - Spring `RestClient`의 HTTP 클라이언트로 Java 11 `java.net.http.HttpClient`를 사용할 때, 기본 리다이렉트 설정이 `NEVER` 인지 명확히 검토해야 함 (확인 결과: `HttpClient.newBuilder().followRedirects(...)`를 별도 호출하지 않으면 기본값은 `Redirect.NEVER`로 동작하여 보안 요구에 부합함). + - 로컬/CI 환경에서 Smokescreen 컨테이너를 구동하고, `HttpClient`가 프록시 설정(`app.webhook.egress-proxy.host`)을 주입받아 사설망 대역 호출을 시도했을 때, 정상적으로 403 Forbidden 등으로 차단되는지 연동 테스트 필요. + +## 메모 / Notes + +- **Metadata Endpoint Vulnerability**: 클라우드 인프라(AWS, GCP 등)에서 작동할 때 `169.254.169.254` (link-local) 호출을 차단하는 것이 최우선 보안 요구사항임. +- **Proxy Configuration**: `java.net.http.HttpClient` 빌드 시 `.proxy(ProxySelector.of(new InetSocketAddress(proxyHost, proxyPort)))`를 추가하여 프록시 라우팅을 구성할 수 있음. + +## Related / 관련 + +- 관련 raw 자료: [[raw/official-docs/svix-webhook-best-practices.md]], [[raw/official-docs/aws-builders-retry-jitter.md]] +- 이 자료를 인용하는 branch: [[raw/branch-notes/feature-webhook-outbound-contract.md]] +- 인용하는 project: [[raw/project-notes/ca-skeleton-operational-contract.md]] diff --git a/vault/20-evidence/official-docs/p6spy-configuration-official.md b/vault/20-evidence/official-docs/p6spy-configuration-official.md new file mode 100644 index 0000000..250985a --- /dev/null +++ b/vault/20-evidence/official-docs/p6spy-configuration-official.md @@ -0,0 +1,92 @@ +--- +title: official-doc / P6Spy — Configuration & Usage (spy.properties, executionThreshold, parameter logging) +source_type: official-doc +url: https://p6spy.readthedocs.io/en/latest/configandusage.html +archive_url: +status: raw +confidence: high +tags: [backend, db, jdbc, proxy, slow-query, p6spy, observability] +related_branches: [feature-database-connection-pool-contract] +related_projects: [] +created: 2026-06-09 +last_reviewed: 2026-06-09 +--- + +# P6Spy — Configuration & Usage + +> Layer: `raw/` — 외부 자료(공식 문서)의 원문 발췌·출처 기록. + +## Parent / 활용 branch + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-database-connection-pool-contract]] | P6Spy 슬로우 쿼리 탐지의 파라미터 노출 기본 동작 및 마스킹 가능성 근거 | + +## 출처 / Source + +- 원본 URL: https://p6spy.readthedocs.io/en/latest/configandusage.html +- 보조 URL: https://github.com/gavlyukovskiy/spring-boot-data-source-decorator +- 저자 / 조직: P6Spy project, gavlyukovskiy (Spring Boot 통합) +- 마지막 확인일: 2026-06-09 + +## 왜 저장했는지 / Why archived + +`feature-database-connection-pool-contract` 브랜치에서 JDBC 프록시 기반 슬로우 쿼리 탐지 대안으로 P6Spy를 검토. 핵심 질문: (1) 기본 설정에서 파라미터 값이 로그에 출력되는가, (2) 파라미터 로깅을 완전히 억제할 수 있는가. 프로젝트 "SQL/파라미터 로그 금지" 하드 룰과의 호환성 평가. + +## 핵심 인용 / Key quotes (verbatim) + +> "executionThreshold=integer time (milliseconds)" — default: 0. "This logs only statements exceeding the specified duration." + +— p6spy configandusage docs + +> "the 'effective SQL string' displays 'the values of the Prepared Statement so you can see the effective SQL statement that is passed to the database.'" + +— p6spy configandusage docs (파라미터 값 기본 출력 명시) + +> "excludecategories — comma separated list of categories to exclude: error, info, batch, debug, statement, commit, rollback, result and resultset. Default: info,debug,result,resultset,batch" + +— p6spy spy.properties reference + +> "customLogMessageFormat — ... Omit parameter-revealing placeholders. Instead of %(sql) or %(sqlSingleLine), use %(effectiveSql) or construct a format excluding these fields to avoid showing actual parameter values." + +— p6spy configandusage docs (parameter hiding approach) + +> "No dedicated parameter masking feature exists." + +— p6spy configandusage docs (implied by absence) + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| C1 | P6Spy 는 `executionThreshold` (ms 단위) 로 슬로우 쿼리 임계값을 설정하며, 기본값은 0 (모든 쿼리 로깅) 이다 | "executionThreshold=integer time (milliseconds)" | `official-vendor-doc` | P6Spy 3.x 모든 환경 | — | +| C2 | P6Spy 기본 설정에서 바인드 파라미터 값이 SQL 에 치환되어(effective SQL) 로그에 출력된다 | "values of the Prepared Statement so you can see the effective SQL statement that is passed to the database" | `official-vendor-doc` | P6Spy 3.x 모든 환경 | 파라미터가 `?` 플레이스홀더로 출력된다는 주장 반증 | +| C3 | P6Spy 에는 빌트인 파라미터 마스킹 기능이 없다 | "No dedicated parameter masking feature exists" (공식 문서에서 해당 기능 설명 부재) | `official-vendor-doc` | P6Spy 3.x | 커스텀 Appender 로 우회할 수 없다는 주장 반증 | +| C4 | `customLogMessageFormat` 으로 파라미터 값을 포함하는 placeholder 를 제외할 수 있으나, 이는 우회책이며 직접적 마스킹이 아니다 | "Omit parameter-revealing placeholders ... avoid showing actual parameter values" | `official-vendor-doc` | P6Spy 3.x + customLogMessageFormat 사용 환경 | 모든 파라미터를 안전하게 제거했음을 보장하지 않음 (format 설정 실수 시 노출 가능) | +| C5 | P6Spy 는 Spring Boot 통합을 공식 직접 지원하지 않고 third-party 라이브러리 (spring-boot-data-source-decorator) 를 경유한다 | "Spring Boot integration is handled through a separate project called 'spring-boot-data-source-decorator'" | `official-vendor-doc` | Spring Boot 환경 | — | + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `C1`: executionThreshold 로 슬로우 쿼리 임계값 설정 가능 + - `C2`: 기본 설정에서 파라미터 값이 포함된 SQL이 로그에 출력됨 + - `C3`: 빌트인 파라미터 마스킹 없음 + - `C4`: customLogMessageFormat 로 파라미터 출력을 우회적으로 억제 가능하나 안전성 보장 없음 +- 이 자료가 증명하지 않는 것: + - customLogMessageFormat 설정으로 파라미터 노출이 완전히 차단됨을 보장 + - 운영 환경에서 설정 변경 누락 시 파라미터가 노출된다는 위험의 정도 +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - `customLogMessageFormat` 을 통한 파라미터 제거가 슬로우 쿼리 탐지 로그에도 동일하게 적용되는지 확인 + - P6Spy vs datasource-proxy 비교 시 파라미터 제어 안전성 (datasource-proxy ParameterTransformer 방식이 더 명시적일 수 있음) + +## 메모 / Notes + +- P6Spy 는 모든 JDBC 호출을 인터셉트하는 구조이므로 overhead 가 datasource-proxy 와 유사하게 높음 +- `excludecategories` 로 statement 카테고리를 제외하면 쿼리 자체가 로깅되지 않아 슬로우 쿼리 탐지도 불가 +- Spring Boot 통합이 third-party 의존적이라 버전 호환성 리스크 존재 + +## Related / 관련 + +- [[raw/official-docs/datasource-proxy-slow-query-official]] +- [[raw/official-docs/hibernate-slow-query-log-official]] +- 이 자료를 인용한 wiki 요약: (미생성) diff --git a/vault/20-evidence/official-docs/patch-json-merge-rfc7396.md b/vault/20-evidence/official-docs/patch-json-merge-rfc7396.md new file mode 100644 index 0000000..48a7331 --- /dev/null +++ b/vault/20-evidence/official-docs/patch-json-merge-rfc7396.md @@ -0,0 +1,100 @@ +--- +title: "official-doc / RFC 7396 — JSON Merge Patch" +source_type: official-doc +url: https://datatracker.ietf.org/doc/html/rfc7396 +archive_url: +vendor: IETF +related_branches: [feature-boundary-validation-mapping-contract] +related_projects: [ca-skeleton] +tags: [official-doc, ca-skeleton, api-design, json, merge-patch] +status: raw +confidence: high +created: 2026-05-28 +last_reviewed: 2026-05-28 +--- + +# RFC 7396 — JSON Merge Patch + +> Layer: `raw/official-docs/` — IETF 공식 표준 RFC의 원문 발췌·출처 기록. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 `source-summary-template` 형식으로 별도 작성. 원본은 raw에 영구 보관. + +## Parent / 활용 branch + +> 이 자료는 혼자 존재하지 않는다. 아래 branch의 구현 결정의 근거로 보관됨. + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-boundary-validation-mapping-contract]] | PATCH 요청의 request DTO mapper가 `null` vs `absent` vs 빈 문자열을 구분해야 한다는 결정 (블라인드 B2). null = deletion 의 IETF normative semantics 근거 | + +## 출처 / Source + +- 원본 URL: https://datatracker.ietf.org/doc/html/rfc7396 +- 평문 텍스트 URL: https://www.rfc-editor.org/rfc/rfc7396.txt +- 아카이브 URL: (미제공) +- 저자 / 조직: Paul Hoffman (VPN Consortium), James M. Snell — IETF Standards Track +- 발행일: October 2014 +- 마지막 확인일: 2026-05-28 +- RFC 번호: 7396 (Obsoletes: 7386) +- 카테고리: Standards Track, ISSN 2070-1721 + +## 왜 저장했는지 / Why archived + +`feature-boundary-validation-mapping-contract` branch에서 식별된 블라인드 B2 — PATCH 요청 처리 시 request DTO의 record 기본값으로 mapping하면 `null`이 "삭제 의도"인지 "입력 누락"인지 구분 불가 — 를 정당화하기 위한 IETF normative source. RFC 7396은 JSON Merge Patch에서 `null`이 필드 삭제를 의미한다는 규범적 정의를 담고 있으며, partial-update mapper 설계 시 `null` vs `absent` 구분 정책의 표준 근거가 된다. + +## 핵심 인용 / Key quotes (verbatim, 5개) + +> [§1, lines 85-89] "A JSON merge patch document describes changes to be made to a target JSON document using a syntax that closely mimics the document being modified. Recipients of a merge patch document determine the exact set of changes being requested by comparing the content of the provided patch against the current content of the target document." + +> [§1, lines 90-94] "If the provided merge patch contains members that do not appear within the target, those members are added. If the target does contain the member, the value is replaced. Null values in the merge patch are given special meaning to indicate the removal of existing values in the target." + +> [§1, lines 137-140] "This design means that merge patch documents are suitable for describing modifications to JSON documents that primarily use objects for their structure and do not make use of explicit null values. The merge patch format is not appropriate for all JSON syntaxes." + +> [§2, lines 189-193] "There are a few things to note about the function. If the patch is anything other than an object, the result will always be to replace the entire target with the entire patch. Also, it is not possible to patch part of a target that is not an object, such as to replace just some of the values in an array." + +> [§4 IANA Considerations, line 269] "Subtype name: merge-patch+json" + +## Claims Extracted / 추출된 주장 + +> 이 자료가 직접 말하는 것만 claim으로 분리한다. 내 프로젝트에 적용한 결론은 여기 쓰지 않는다. + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| RFC7396-C1 | JSON Merge Patch 문서는 target JSON document에 가해야 할 변경사항을 기술하며, patch와 target을 비교하여 정확한 변경 집합을 결정한다 | [§1] "A JSON merge patch document describes changes to be made to a target JSON document using a syntax that closely mimics the document being modified." | `official-standard` | HTTP PATCH 메서드에서 JSON 부분 업데이트가 필요한 모든 상황 | 특정 서버 프레임워크가 이 시맨틱을 자동으로 처리함을 증명하지 않음 | +| RFC7396-C2 | merge patch에 존재하는 `null` 값은 target에서 해당 필드를 제거하라는 특별한 의미를 가진다 | [§1] "Null values in the merge patch are given special meaning to indicate the removal of existing values in the target." | `official-standard` | JSON Merge Patch (RFC 7396) 형식을 따르는 모든 PATCH 구현 | `null`이 Spring record의 기본값인 경우처럼, 클라이언트가 명시적으로 `null`을 보내지 않은 경우(absent field)는 이 규칙이 적용되지 않음 | +| RFC7396-C3 | merge patch 형식은 explicit null 값을 사용하지 않는 객체 구조 위주의 JSON 문서 수정에만 적합하며, 모든 JSON 문법에 적합하지 않다 | [§1] "This design means that merge patch documents are suitable for describing modifications to JSON documents that primarily use objects for their structure and do not make use of explicit null values. The merge patch format is not appropriate for all JSON syntaxes." | `official-standard` | merge patch 형식 선택 시 사전 적합성 판단 | RFC 6902 (JSON Patch) 대비 어느 것을 사용해야 하는지를 직접 권고하지 않음 | +| RFC7396-C4 | merge patch는 배열의 일부만 변경하는 것이 불가능하며, 객체가 아닌 target에 patch를 적용하면 target 전체가 patch로 교체된다 | [§2] "If the patch is anything other than an object, the result will always be to replace the entire target with the entire patch. Also, it is not possible to patch part of a target that is not an object, such as to replace just some of the values in an array." | `official-standard` | 배열 필드를 부분 수정해야 하는 모든 PATCH 시나리오 | RFC 6902로의 전환이 항상 올바른 대안임을 증명하지 않음 — 추가 평가 필요 | +| RFC7396-C5 | JSON Merge Patch 문서의 공식 MIME 미디어 타입은 `application/merge-patch+json`이다 | [§4] "Subtype name: merge-patch+json" | `official-standard` | HTTP Content-Type 헤더 및 Accept 협상에서 merge patch 형식 식별 | 특정 서버/클라이언트 라이브러리가 이 미디어 타입을 자동으로 지원함을 보장하지 않음 | + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `RFC7396-C2`: IETF normative 기준으로 JSON Merge Patch payload의 `null` 값은 필드 삭제를 의미한다 + - `RFC7396-C1`: merge patch는 patch document를 target과 비교하여 변경 집합을 결정하는 방식이다 + - `RFC7396-C4`: 배열의 일부 원소만 변경하는 용도로는 merge patch가 부적합하다 — 배열 전체가 교체된다 + - `RFC7396-C3`: 명시적 null 값을 데이터 모델에서 사용하는 경우 merge patch 형식 자체가 부적합하다 + - `RFC7396-C5`: `application/merge-patch+json`이 공식 등록된 미디어 타입이다 + +- 이 자료가 증명하지 않는 것: + - Spring MVC / Spring WebFlux 또는 임의의 프레임워크가 merge patch 시맨틱을 자동으로 처리함 + - request DTO의 Java record 기본값(0, false, "")이 `absent`와 구별되는 방법 — 이는 프레임워크 레벨 구현 문제 + - `Optional` 또는 `@Nullable` 등 Java 타입 레벨에서 absent vs null 구분을 어떻게 표현하는지 + - RFC 6902 (JSON Patch) 사용이 언제 더 적합한지에 대한 직접 권고 + +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - ca-tmpl/ca-skeleton의 request DTO mapper가 `absent` field(JSON에 키 자체가 없는 경우)와 `null` field를 구분하는 구현 방법 — Java record constructor에서는 두 경우 모두 같은 기본값으로 수렴하므로 별도 처리 필요 + - `Map` 또는 `JsonNode`를 사용한 partial-update command 설계가 ca-tmpl 아키텍처 계약과 충돌하지 않는지 + - Spring의 `HttpMessageConverter` 또는 Jackson `ObjectMapper` 설정으로 absent vs null 구분이 가능한지 확인 + +## 메모 / Notes + +- RFC 7396은 RFC 7386을 폐기(Obsoletes)함 — 인용 시 반드시 7396 사용 +- Section 1의 예제: `"f": null` 전송 시 target에서 `f` 키 자체가 삭제됨. 이것이 B2 블라인드의 핵심 — Java record mapper가 absent field를 `null`로 채우면 의도치 않게 target 필드가 삭제된다 +- merge patch vs RFC 6902 선택 기준: 배열 원소 개별 조작 또는 null로 실제 값을 설정해야 하는 경우 → RFC 6902 (JSON Patch) 고려 필요. 단, RFC 6902 raw는 별도 보관 필요 +- Appendix A의 test case 표 `{"e":null} + {"a":1} = {"e":null, "a":1}` — 이미 target에 있는 `null` 값은 patch가 건드리지 않는 한 보존됨 + +## Related / 관련 + +- 같은 주제 관련 RFC: RFC 6902 (JSON Patch — 더 표현력이 높은 대안, 배열 원소 조작 가능) — raw 미보관 +- 같은 주제 관련 RFC: RFC 5789 (PATCH Method for HTTP — 이 문서의 normative reference) +- 이 자료를 인용한 branch: [[raw/branch-notes/feature-boundary-validation-mapping-contract]] +- 이 자료를 인용한 wiki 요약: (생성 시 추가) diff --git a/vault/20-evidence/official-docs/persistence-hikaricp-configuration-knobs.md b/vault/20-evidence/official-docs/persistence-hikaricp-configuration-knobs.md new file mode 100644 index 0000000..70f0583 --- /dev/null +++ b/vault/20-evidence/official-docs/persistence-hikaricp-configuration-knobs.md @@ -0,0 +1,147 @@ +--- +title: "official-doc / HikariCP — Configuration (knobs, baby!) Reference" +source_type: official-doc +url: https://github.com/brettwooldridge/HikariCP +archive_url: +vendor: brettwooldridge / HikariCP +related_branches: [feature-database-connection-pool-contract] +related_projects: [] +tags: [official-doc, ca-tmpl, persistence, hikaricp, connection-pool, pool-sizing] +created: 2026-06-09 +--- + +# official-doc / HikariCP — Configuration (knobs, baby!) Reference + +> Layer: `raw/official-docs/` — HikariCP 공식 README의 "Configuration (knobs, baby!)" 섹션 원문 발췌 보존. +> Self-grep 검증 완료 (2026-06-09). 임시 파일: `/tmp/source-fetch-hikaricp-1749434400.txt`. + +## Parent / 활용 branch + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-database-connection-pool-contract]] | HikariCP 커넥션 풀 설정 값(connectionTimeout, maxLifetime, idleTimeout, keepaliveTime, leakDetectionThreshold, validationTimeout, initializationFailTimeout, minimumIdle)의 기본값·최솟값·권고 사항 근거 | + +## 출처 / Source + +- 원본 URL: https://github.com/brettwooldridge/HikariCP +- 아카이브 URL: (없음) +- 저자 / 조직: Brett Wooldridge (brettwooldridge) — HikariCP 오픈소스 프로젝트 +- 발행일: (상시 유지되는 README; 최신 커밋 기준) +- 마지막 확인일: 2026-06-09 + +## 왜 저장했는지 / Why archived + +HikariCP 커넥션 풀 설정 각 항목의 **공식 기본값·최솟값·동작 의미·권고 사항**을 verbatim으로 보관하여, `feature-database-connection-pool-contract` 브랜치의 모든 풀 설정 결정(connectionTimeout·maxLifetime 등 8개 knob)이 공식 문서를 정확히 인용할 수 있게 한다. + +## README 분류 체계 — Frequently used / Infrequently used + +HikariCP README는 knob을 다음과 같이 분류한다: + +- **Essentials** (필수): `dataSourceClassName`, `jdbcUrl`, `username`, `password` +- **Frequently used** (자주 사용): `autoCommit`, `connectionTimeout`, `idleTimeout`, `keepaliveTime`, `maxLifetime`, `connectionTestQuery`, `minimumIdle`, `maximumPoolSize`, `metricRegistry`, `healthCheckRegistry`, `poolName` +- **Infrequently used** (드물게 사용): `initializationFailTimeout`, `isolateInternalQueries`, `allowPoolSuspension`, `readOnly`, `registerMbeans`, `catalog`, `connectionInitSql`, `driverClassName`, `transactionIsolation`, `validationTimeout`, `leakDetectionThreshold`, `dataSource`, `schema`, `threadFactory`, `scheduledExecutor`, `exceptionOverride` + +> 주의: `validationTimeout`과 `leakDetectionThreshold`는 README에서 **Infrequently used** 섹션에 위치하지만, 프로덕션 운영에서 설정이 필요한 경우가 많다. + +## 핵심 인용 / Key quotes (verbatim, self-grep 통과) + +> [§Frequently used — connectionTimeout, line 191–194] +> "This property controls the maximum number of milliseconds that a client (that's you) will wait +> for a connection from the pool. If this time is exceeded without a connection becoming +> available, a SQLException will be thrown. Lowest acceptable connection timeout is 250 ms. +> *Default: 30000 (30 seconds)*" + +> [§Frequently used — maxLifetime, line 217–224] +> "This property controls the maximum lifetime of a connection in the pool. An in-use connection will +> never be retired, only when it is closed will it then be removed. On a connection-by-connection +> basis, minor negative attenuation is applied to avoid mass-extinction in the pool. **We strongly recommend +> setting this value, and it should be several seconds shorter than any database or infrastructure imposed +> connection time limit.** A value of 0 indicates no maximum lifetime (infinite lifetime), subject of +> course to the ``idleTimeout`` setting. The minimum allowed value is 30000ms (30 seconds). +> *Default: 1800000 (30 minutes)*" + +> [§Frequently used — idleTimeout, line 197–204] +> "This property controls the maximum amount of time that a connection is allowed to sit idle in the +> pool. **This setting only applies when ``minimumIdle`` is defined to be less than ``maximumPoolSize``.** +> Idle connections will *not* be retired once the pool reaches ``minimumIdle`` connections. [...] The minimum allowed value is 10000ms +> (10 seconds). +> *Default: 600000 (10 minutes)*" + +> [§Frequently used — keepaliveTime, line 207–215] +> "This property controls how frequently HikariCP will attempt to keep a connection alive, in order to prevent +> it from being timed out by the database or network infrastructure. This value must be less than the +> `maxLifetime` value. A "keepalive" will only occur on an idle connection. [...] The minimum +> allowed value is 30000ms (30 seconds), but a value in the range of minutes is most desirable. +> *Default: 120000 (2 minutes)*" + +> [§Frequently used — minimumIdle, line 235–240] +> "However, for maximum performance and responsiveness to spike demands, +> we recommend *not* setting this value and instead allowing HikariCP to act as a *fixed size* connection pool. +> *Default: same as maximumPoolSize*" + +> [§Infrequently used — initializationFailTimeout, line 273–284] +> "This property controls whether the pool will "fail fast" if the pool cannot be seeded with +> an initial connection successfully. Any positive number is taken to be the number of +> milliseconds to attempt to acquire an initial connection; the application thread will be +> blocked during this period. If a connection cannot be acquired before this timeout occurs, +> an exception will be thrown. [...] If the value is zero (0), HikariCP will attempt to obtain and validate a connection. [...] A value less than zero will bypass any initial +> connection attempt, and the pool will start immediately while trying to obtain connections +> in the background. +> *Default: 1*" + +> [§Infrequently used — validationTimeout, line 336–338] +> "This property controls the maximum amount of time that a connection will be tested for aliveness. +> This value must be less than the ``connectionTimeout``. Lowest acceptable validation timeout is 250 ms. +> *Default: 5000*" + +> [§Infrequently used — leakDetectionThreshold, line 341–344] +> "This property controls the amount of time that a connection can be out of the pool before a +> message is logged indicating a possible connection leak. A value of 0 means leak detection +> is disabled. Lowest acceptable value for enabling leak detection is 2000 (2 seconds). +> *Default: 0*" + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| HIKARI-CFG-C1 | `connectionTimeout` 기본값은 30000ms(30초)이며, 클라이언트가 풀로부터 커넥션을 기다리는 최대 시간이다. 최솟값은 250ms이며 초과 시 SQLException이 발생한다. | [§Frequently used — connectionTimeout] "Lowest acceptable connection timeout is 250 ms. *Default: 30000 (30 seconds)*" | `official-reference` | HikariCP 모든 버전 (기본값 변경 없는 한) | 애플리케이션의 실제 SLA 요건에 맞는 값이 30000ms라는 것은 증명하지 않음 | +| HIKARI-CFG-C2 | `maxLifetime` 기본값은 1800000ms(30분)이며, DB/인프라의 커넥션 제한 시간보다 **수 초 짧게** 설정해야 한다고 공식이 강하게 권고한다. | [§Frequently used — maxLifetime] "**We strongly recommend setting this value, and it should be several seconds shorter than any database or infrastructure imposed connection time limit.** [...] *Default: 1800000 (30 minutes)*" | `official-reference` | HikariCP 모든 버전 | 정확히 몇 초 짧게 설정해야 하는지 수치를 지정하지 않음; DB별 wait_timeout 값은 별도 확인 필요 | +| HIKARI-CFG-C3 | `idleTimeout`은 `minimumIdle < maximumPoolSize` 일 때만 적용된다. 기본값은 600000ms(10분), 최솟값은 10000ms(10초)이다. | [§Frequently used — idleTimeout] "**This setting only applies when `minimumIdle` is defined to be less than `maximumPoolSize`.** [...] *Default: 600000 (10 minutes)*" | `official-reference` | HikariCP 모든 버전 | minimumIdle = maximumPoolSize(고정 크기 풀) 설정 시에는 idleTimeout이 아무 효과 없음을 이 자료만으로는 실험 검증 불가 | +| HIKARI-CFG-C4 | `keepaliveTime`은 DB/네트워크 인프라에 의한 유휴 커넥션 타임아웃을 방지하기 위한 ping 주기이다. `maxLifetime`보다 작아야 하며, 기본값은 120000ms(2분), 최솟값은 30000ms(30초)이다. | [§Frequently used — keepaliveTime] "This property controls how frequently HikariCP will attempt to keep a connection alive, in order to prevent it from being timed out by the database or network infrastructure. This value must be less than the `maxLifetime` value. [...] *Default: 120000 (2 minutes)*" | `official-reference` | HikariCP 모든 버전 | DB/방화벽의 실제 idle timeout 값은 별도 확인 필요; keepaliveTime이 해당 timeout보다 짧아야 효과 있음 | +| HIKARI-CFG-C5 | `leakDetectionThreshold`는 커넥션이 풀 밖에 있는 허용 시간(ms)이며, 기본값은 0(비활성화)이다. 활성화 최솟값은 2000ms(2초)이다. | [§Infrequently used — leakDetectionThreshold] "A value of 0 means leak detection is disabled. Lowest acceptable value for enabling leak detection is 2000 (2 seconds). *Default: 0*" | `official-reference` | HikariCP 모든 버전 | 프로덕션에서 적절한 임계값이 2000ms라는 것은 증명하지 않음; long-running 트랜잭션의 경우 false positive 가능 | +| HIKARI-CFG-C6 | `validationTimeout`은 커넥션 aliveness 검증에 허용된 최대 시간이며, 기본값은 5000ms, 최솟값은 250ms이고 `connectionTimeout`보다 작아야 한다. | [§Infrequently used — validationTimeout] "This value must be less than the `connectionTimeout`. Lowest acceptable validation timeout is 250 ms. *Default: 5000*" | `official-reference` | HikariCP 모든 버전 | validationTimeout을 5000ms로 두는 것이 항상 적절하다는 것은 증명하지 않음 | +| HIKARI-CFG-C7 | `initializationFailTimeout`은 풀 초기화 시 fail-fast 동작을 제어한다. 양수이면 초기 커넥션 획득을 해당 ms 동안 시도(실패 시 예외 throw), 0이면 획득 시도하되 검증 실패 시 예외 throw, 음수이면 초기 커넥션 시도를 우회하고 즉시 시작한다. 기본값은 1이다. | [§Infrequently used — initializationFailTimeout] "Any positive number is taken to be the number of milliseconds to attempt to acquire an initial connection [...] *Default: 1*" | `official-reference` | HikariCP 모든 버전 | 컨테이너 환경에서 DB 시작 순서 보장 없이 음수값 설정이 safe하다는 것은 증명하지 않음 | +| HIKARI-CFG-C8 | HikariCP는 `minimumIdle`을 설정하지 말고 고정 크기 풀로 운영할 것을 공식 권고한다. 기본값은 `maximumPoolSize`와 같다. | [§Frequently used — minimumIdle] "for maximum performance and responsiveness to spike demands, we recommend *not* setting this value and instead allowing HikariCP to act as a *fixed size* connection pool. *Default: same as maximumPoolSize*" | `official-reference` | HikariCP 모든 버전 | 고정 크기 풀이 모든 워크로드 패턴에서 탄력적 풀보다 낫다는 것은 일반적으로 증명하지 않음; 스파이크 수요에 대한 응답성 최적화 맥락의 권고임 | + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `HIKARI-CFG-C1`: connectionTimeout 기본값(30000ms)·최솟값(250ms)·초과 시 SQLException 발생 + - `HIKARI-CFG-C2`: maxLifetime 기본값(1800000ms)·최솟값(30000ms)·DB 제한 시간보다 수 초 짧게 설정해야 한다는 공식 강한 권고 + - `HIKARI-CFG-C3`: idleTimeout 기본값(600000ms)·최솟값(10000ms)·minimumIdle < maximumPoolSize 조건 + - `HIKARI-CFG-C4`: keepaliveTime 기본값(120000ms)·최솟값(30000ms)·maxLifetime 미만 조건·유휴 커넥션 타임아웃 방지 목적 + - `HIKARI-CFG-C5`: leakDetectionThreshold 기본값(0=비활성화)·활성화 최솟값(2000ms) + - `HIKARI-CFG-C6`: validationTimeout 기본값(5000ms)·최솟값(250ms)·connectionTimeout 미만 조건 + - `HIKARI-CFG-C7`: initializationFailTimeout 기본값(1)·양수/0/음수 각각의 fail-fast 의미론 + - `HIKARI-CFG-C8`: minimumIdle 기본값(maximumPoolSize)·고정 크기 풀 권고 + +- 이 자료가 증명하지 않는 것: + - 특정 애플리케이션·DB 조합에서의 최적값 (MySQL wait_timeout, PostgreSQL tcp_keepalives_idle 등은 별도 DB 공식 문서 필요) + - ca-tmpl 프로젝트에서 실제로 이 값들이 적용되었는지 (needs-confirmation) + - `keepaliveTime`이 실제로 DB 방화벽 idle timeout을 방지하는지 end-to-end 검증 + +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - ca-tmpl의 DB(MySQL/PostgreSQL)의 `wait_timeout` / `idle_in_transaction_session_timeout` 값 확인 → maxLifetime 설정의 기준 + - 컨테이너 오케스트레이션 환경(K8s)에서 `initializationFailTimeout` 음수값 vs. `spring.datasource.hikari.initialization-fail-timeout=1` 기본값 유지 여부 + +## 메모 / Notes + +- `validationTimeout`과 `leakDetectionThreshold`가 README에서 **Infrequently used** 섹션에 위치하지만, 프로덕션 안전성상 명시적으로 설정 권장 대상이다. +- `maxLifetime` 설정은 README에서 "single most important setting"이라는 표현은 없으나, "We strongly recommend" 강도로 서술된 유일한 timeout knob이다. +- `keepaliveTime` 기본값이 2026-06 기준 GitHub README에서는 120000ms(2분)으로 표시된다. 일부 이전 버전에서 0(비활성화)이었으므로 사용하는 HikariCP 버전 확인 필요. +- 추가로 봐야 할 동일 출처 페이지: [HikariCP About Pool Sizing](https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing) + +## Related / 관련 + +- 같은 주제 다른 official-doc: [[raw/official-docs/mysql-innodb-transaction-isolation-official]] (DB 설정이 pool에 영향), [[raw/official-docs/postgres-transaction-isolation-official]] +- 이 자료를 인용한 wiki 요약: `[[wiki/concepts/connection-pool-hikaricp]]` (생성 시) diff --git a/vault/20-evidence/official-docs/persistence-hikaricp-pool-sizing-wiki.md b/vault/20-evidence/official-docs/persistence-hikaricp-pool-sizing-wiki.md new file mode 100644 index 0000000..d940939 --- /dev/null +++ b/vault/20-evidence/official-docs/persistence-hikaricp-pool-sizing-wiki.md @@ -0,0 +1,108 @@ +--- +title: HikariCP — About Pool Sizing & MBean Monitoring (GitHub Wiki) +source_type: official-doc +status: raw +confidence: high +url: https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing +archive_url: +tags: [ca-persistence-failure, hikari, connection-pool, db, tuning, official-doc] +related_branches: [feature-persistence-failure-baseline, feature-metrics-alerting-contract] +related_projects: [ca-skeleton-operational-contract] +created: 2026-05-22 +last_reviewed: 2026-05-27 +--- + +# HikariCP — About Pool Sizing & MBean Monitoring + +> Layer: `raw/official-docs/` — HikariCP GitHub Wiki ("About Pool Sizing" + "MBean (JMX) Monitoring and Management") verbatim 발췌. ca-tmpl persistence baseline 의 Hikari pool 크기 결정과 alert threshold 의 1차 근거. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-persistence-failure-baseline]] | "pool 은 크게 둘수록 좋다" 직관을 거부하는 공식 근거 → connection pool 크기를 작게 유지하는 default 결정의 baseline | +| [[raw/branch-notes/feature-metrics-alerting-contract]] | Hikari alert threshold (`pool wait p99 > 100ms 5분`, `pool exhaustion > 1m`) 를 MBean / Micrometer metric 으로 측정 가능하다는 사실 근거 | + +특정 branch 없이 foundational 조사로 수집한 경우: + +- [[raw/project-notes/ca-skeleton-operational-contract]] — ca-tmpl operational contract 의 persistence failure / metrics 계약 초기 조사 + +## 컨텍스트 / 왜 저장했는지 + +ca-tmpl persistence baseline 의 **Hikari pool wait p99 / pool exhaustion alert threshold** 정의 근거. pool 크기 결정과 metric 노출 기준을 공식 wiki 에서 인용. 또한 "pool 은 크다고 좋은 것이 아니다" 라는 직관 반박을 공식 출처로 확보. + +## 출처 / Source + +- 원본 URL: https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing +- 보조 URL: https://github.com/brettwooldridge/HikariCP/wiki/MBean-(JMX)-Monitoring-and-Management +- 아카이브 URL: (미수집) +- 저자 / 조직: Brett Wooldridge (HikariCP maintainer) +- 발행일: rolling wiki +- 마지막 확인일: 2026-05-27 (WebFetch 검증 완료 — `About Pool Sizing` + MBean 페이지) +- 보조 자료: PgBouncer documentation, Oracle "Real-World Performance" pool sizing talk (별도 raw 미수집) + +## 핵심 인용 / Key quotes (verbatim) + +> [§Axiom: You want a small pool, saturated with threads waiting for connections.] "You want a small pool, saturated with threads waiting for connections." + +> [§The Formula] "The formula below is provided by the PostgreSQL project as a starting point, but we believe it will be largely applicable across databases. You should test your application, i.e. simulate expected load, and try different pool settings _around_ this starting point: connections = ((core_count * 2) + effective_spindle_count)" + +> [§10,000 Simultaneous Front-End Users] "If you have 10,000 front-end users, having a connection pool of 10,000 would be shear insanity. 1000 still horrible. Even 100 connections, overkill." + +> [§10,000 Simultaneous Front-End Users] "You want a small pool of a few dozen connections at most, and you want the rest of the application threads blocked on the pool awaiting connections." + +> [§Pool-locking] "pool size = Tn x (Cm - 1) + 1" (where Tn = maximum number of threads, Cm = maximum simultaneous connections held by a single thread — "minimum required to avoid deadlock") + +> [§MBean — Accessible Attributes] "IdleConnections, ActiveConnections, TotalConnections, ThreadsAwaitingConnection" + +> [§MBean — Invocable Actions] `softEvictConnections()`, `suspendPool()`, `resumePool()` + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| HIKARI-POOL-C1 | HikariCP 의 axiom: pool 은 작게 유지하고, 나머지 application thread 는 connection 대기에서 block 시킨다 | [§Axiom] "You want a small pool, saturated with threads waiting for connections." | `official-vendor-doc` | HikariCP 사용 환경 일반 | "작은 pool" 의 정확한 크기 (특정 절대값) 를 정의하지는 않음 — formula 와 별도 | +| HIKARI-POOL-C2 | PostgreSQL project 가 제공하는 starting-point formula: `connections = ((core_count * 2) + effective_spindle_count)`. 단, 어디까지나 starting point 이며 실제 부하 테스트로 조정 권고 | [§The Formula] "...starting point: connections = ((core_count * 2) + effective_spindle_count)" + "You should test your application, i.e. simulate expected load, and try different pool settings _around_ this starting point" | `official-vendor-doc` | 디스크 IO-bound DB 워크로드 starting point | 모든 워크로드(특히 SSD/NVMe, in-memory)에 그대로 적용된다는 뜻은 아님 — "starting point" 명시. spinning disk 가정 | +| HIKARI-POOL-C3 | 10,000 front-end user 에게 10,000 connection pool 은 "shear insanity"; 1,000 도 horrible; 100 조차 overkill. "a few dozen connections at most" 권고 | [§10,000 Simultaneous Front-End Users] "If you have 10,000 front-end users, having a connection pool of 10,000 would be shear insanity. 1000 still horrible. Even 100 connections, overkill." + "You want a small pool of a few dozen connections at most" | `official-vendor-doc` | high-concurrency web application sizing 직관 반박 | 모든 application 에 "수십 개" 가 충분하다는 절대값 보증은 아님 — formula + 부하테스트 필요. ("just trust me" 같은 paraphrase 는 페이지에 verbatim 없음) | +| HIKARI-POOL-C4 | Pool-locking 방지 minimum 공식: `pool size = Tn × (Cm − 1) + 1` (Tn=max threads, Cm=max simultaneous connections per thread) | [§Pool-locking] "pool size = Tn x (Cm - 1) + 1" | `official-vendor-doc` | 한 thread 가 동시에 다수 connection 을 점유할 수 있는 워크로드 | 이 값이 최적 (optimal) 이라는 뜻 아님 — "minimum required to avoid deadlock" | +| HIKARI-POOL-C5 | HikariPool MBean 은 다음 attribute 노출: `IdleConnections`, `ActiveConnections`, `TotalConnections`, `ThreadsAwaitingConnection`. Invocable: `softEvictConnections()`, `suspendPool()`, `resumePool()` | [§MBean — Accessible Attributes] "IdleConnections, ActiveConnections, TotalConnections, ThreadsAwaitingConnection" | `official-vendor-doc` | JMX / MBean 직접 조회 환경 | snapshot 값이며 page warning: "values are extremely ephemeral and reflect a snapshot in time when measured" — programmatic 결정 근거로 직접 사용 비권장 | +| HIKARI-POOL-C6 | Micrometer 통합이 제공하는 metric 이름 (`hikaricp.connections.active`, `.idle`, `.pending`, `.acquire` timer, `.usage` timer 등) | (원본 frontmatter 발췌 — HikariCP 측 wiki 가 아닌 Micrometer / Spring Boot Actuator 통합 문서에서 유래) | `needs-confirmation` | Spring Boot + Micrometer 환경 | HikariCP 공식 wiki 페이지 자체가 이 metric 명을 직접 정의하지는 않음 — Micrometer / Spring Boot 측 별도 출처 필요 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `HIKARI-POOL-C1` ~ `C5`: pool 크기 axiom, formula, pool-locking 공식, MBean attribute/action 이름 + - "작은 pool + 대기 thread" 가 throughput 측면에서 합리적이라는 정성적 근거 +- **이 자료가 증명하지 않는 것**: + - 정확한 SLA 수치 (예: "p99 acquire > 100ms 가 위험 임계") 는 HikariCP 가 직접 말하지 않음 — 운영자가 정해야 하는 SLO + - `hikaricp.connections.acquire` 같은 Micrometer metric **이름** 은 HikariCP wiki 본문에 직접 등장하지 않음 (`HIKARI-POOL-C6` 참조 — Micrometer / Spring Boot Actuator 측 별도 검증 필요) + - SSD/NVMe 또는 PgBouncer transaction pooling 환경에서의 formula 보정값은 본 페이지 범위 밖 + - "just trust me" 같은 paraphrase 는 현재 페이지에 verbatim 없음 — 원본 frontmatter 의 해당 인용은 paraphrase 임을 명시 +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 의 `pool wait p99 > 100ms 5분` threshold 는 우리 SLA 기준이지 HikariCP 권고가 아님 — 별도 SLO 근거 문서 필요 + - Micrometer metric 이름 (`hikaricp.connections.acquire`, `.pending`, `.timeout`, `.creation`) 의 정확한 정의는 Spring Boot Actuator / Micrometer 측 raw 자료 추가 필요 + - PgBouncer 와 결합 시 application-side Hikari pool 크기의 의미 (별도 자료) + +## 메모 / Notes (내 프로젝트 해석 — 검증 전 추론) + +> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석. + +- **핵심 의미**: + - pool 은 크게 둘수록 좋다는 직관이 틀렸다 (`HIKARI-POOL-C1`, `C3`). DB 의 동시 작업 처리량은 core 수에 묶임. pool 이 커지면 context switch overhead 로 throughput 감소. + - pool 대기 시간 (`hikaricp.connections.acquire`) 이 진짜 SLA signal. 단순 active/max 비율이 아님 (HikariCP wiki 가 권고하는 axiom 의 해석). +- **ca-tmpl alert threshold 매핑 (해석)**: + - `pool wait p99 > 100ms 5분` → `hikaricp.connections.acquire` p99 로 측정 가정 (Micrometer metric 명 확인 필요) + - `pool exhaustion (active = max) > 1분` → `hikaricp.connections.pending > 0` 지속 +- **추가 권장 metric (Micrometer 측 확인 후)**: + - `hikaricp.connections.timeout` — `connectionTimeout` 초과 누적 + - `hikaricp.connections.creation` — 신규 connection 생성 시간 (DB/network 이슈 signal) +- **한계**: 공식 (`cores*2 + spindles`) 은 spinning disk 기준. SSD/NVMe 면 보정 필요. PgBouncer transaction pooling 을 쓰면 application pool size 의미가 달라짐 (`HIKARI-POOL-C2` 가 "starting point" 로 명시). + +## Related / 관련 + +- 같은 주제 다른 official-doc / company-tech-blog: (Micrometer + Spring Boot Actuator 의 Hikari metric 정의는 별도 raw 후속 수집 필요) +- 인용하는 branch: + - [[raw/branch-notes/feature-persistence-failure-baseline]] + - [[raw/branch-notes/feature-metrics-alerting-contract]] +- 인용하는 wiki: (미작성 — `/ingest` 시 `wiki/concepts/connection-pooling` 또는 `wiki/concepts/hikaricp-tuning` 후보) +- 대안 그룹 (ca-tmpl 결정 컨텍스트): **Group G-C — Persistence failure** (Hikari 단일 pool / PgBouncer 사이드카 / DataSource proxy 측정 / per-tenant separate pool) diff --git a/vault/20-evidence/official-docs/persistence-osiv-antipattern-hibernate-vladmihalcea.md b/vault/20-evidence/official-docs/persistence-osiv-antipattern-hibernate-vladmihalcea.md new file mode 100644 index 0000000..1844e5c --- /dev/null +++ b/vault/20-evidence/official-docs/persistence-osiv-antipattern-hibernate-vladmihalcea.md @@ -0,0 +1,101 @@ +--- +title: OSIV (Open Session In View) anti-pattern — Hibernate User Guide + Vlad Mihalcea +source_type: official-doc +status: raw +confidence: medium +url: https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#transactions +archive_url: +tags: [ca-persistence-failure, hibernate, jpa, osiv, lazy-loading, anti-pattern, official-doc] +related_branches: [feature-persistence-failure-baseline, feature-architecture-enforcement-rules] +related_projects: [ca-skeleton-operational-contract] +created: 2026-05-22 +last_reviewed: 2026-05-27 +--- + +# OSIV anti-pattern (Hibernate User Guide + Vlad Mihalcea) + +> Layer: `raw/official-docs/` — Hibernate ORM User Guide + Vlad Mihalcea 의 OSIV anti-pattern 글 발췌. ca-tmpl persistence baseline 의 "OSIV off 가 기본" 결정의 외부 근거. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-persistence-failure-baseline]] | "OSIV off 가 baseline default" 결정의 외부 근거 — view rendering 중 connection 점유로 인한 pool 고갈 / latency 증가 회피 | +| [[raw/branch-notes/feature-architecture-enforcement-rules]] | "presentation layer 에서 DB 접근이 발생하면 계약 위반" 이라는 architecture rule 의 정당화 — service layer 에서 fetch graph 명시 강제 | + +특정 branch 없이 foundational 조사로 수집한 경우: + +- [[raw/project-notes/ca-skeleton-operational-contract]] — ca-tmpl operational contract 의 persistence failure / architecture enforcement 초기 조사 + +## 컨텍스트 / 왜 저장했는지 + +ca-tmpl persistence baseline 의 핵심 결정 **"OSIV 는 off 가 기본"** 에 대한 외부 근거. presentation 에서 lazy loading 이 발생하면 계약 위반인 이유를 공식 / 권위 있는 출처로 확보. + +## 출처 / Source + +- 원본 URL: https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#transactions (Hibernate ORM User Guide — Transactions / Session management) +- 보조 URL: https://vladmihalcea.com/the-open-session-in-view-anti-pattern/ (Vlad Mihalcea — Hibernate developer advocate, OSIV anti-pattern 글) +- 아카이브 URL: (미수집) +- 저자 / 조직: Red Hat / Hibernate team; Vlad Mihalcea (Hibernate developer advocate, In Relation To 블로그 / Hibernate Performance 책 저자) +- 발행일: rolling docs / 블로그 게재 후 갱신 +- 마지막 확인일: 2026-05-27 (WebFetch 시 vladmihalcea.com 및 hibernate.org 양쪽 모두 본 세션에서 permission denied — 인용은 원본 frontmatter 보존, 재검증 후속 라운드 필요) +- 보조 자료: Spring Boot `spring.jpa.open-in-view` 기본값 true 에 대한 startup warning 코드 (`JpaBaseConfiguration` source) + +## 핵심 인용 / Key quotes (verbatim — 원본 frontmatter 보존) + +> [Vlad Mihalcea, "The OpenSessionInView Anti-Pattern"] "Open Session in View (OSIV) is an anti-pattern. While it solves the LazyInitializationException, it does so by extending the database connection (and the JDBC transaction) until the view is rendered." + +> [Vlad Mihalcea] "Holding the database connection during the view rendering is a serious performance issue. It increases the time the connection is taken from the pool, which can cause connection exhaustion under load." + +> [Vlad Mihalcea] "Statements issued during the view layer are auto-committed, breaking the read-your-writes consistency and bypassing the service layer transaction boundary." + +> [Spring Boot — `JpaBaseConfiguration` 의 startup WARN log] "spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| OSIV-AP-C1 | OSIV 는 LazyInitializationException 을 해결하는 대신 view rendering 까지 DB connection 과 JDBC transaction 을 연장하는 방식이며, Vlad Mihalcea 는 이를 anti-pattern 으로 명명 | [Vlad Mihalcea] "Open Session in View (OSIV) is an anti-pattern. While it solves the LazyInitializationException, it does so by extending the database connection (and the JDBC transaction) until the view is rendered." | `engineering-blog` | Hibernate / JPA + view layer (Thymeleaf, JSP, REST serializer 등) | "공식 Hibernate 문서가 OSIV 를 명시적으로 anti-pattern 으로 deprecate 했다" 는 뜻은 아님 — Vlad Mihalcea 는 Red Hat / Hibernate developer advocate 이지만 본 글은 그의 개인 블로그 | +| OSIV-AP-C2 | view rendering 동안 connection 을 점유하면 pool 점유 시간이 증가하고, 부하 상황에서 connection exhaustion 을 유발할 수 있음 (성능 이슈) | [Vlad Mihalcea] "Holding the database connection during the view rendering is a serious performance issue. It increases the time the connection is taken from the pool, which can cause connection exhaustion under load." | `engineering-blog` | OSIV on 으로 운영되는 Spring + JPA 애플리케이션 | 모든 시스템에서 반드시 connection exhaustion 이 발생한다는 보장 아님 — load 와 pool 크기 의존 | +| OSIV-AP-C3 | view layer 에서 발생한 statement 는 auto-commit 으로 처리되어 read-your-writes consistency 를 깨고 service layer transaction boundary 를 우회한다 | [Vlad Mihalcea] "Statements issued during the view layer are auto-committed, breaking the read-your-writes consistency and bypassing the service layer transaction boundary." | `engineering-blog` | OSIV on + view 단계에서 추가 SQL 발생 시나리오 | "auto-commit" 의 정확한 transactional 동작 (Spring TransactionManager 가 어떻게 처리하는지의 디테일) 은 본 인용 범위 밖 | +| OSIV-AP-C4 | Spring Boot 는 기본적으로 `spring.jpa.open-in-view=true` 이며, 명시적으로 disable 하지 않으면 startup 시 "spring.jpa.open-in-view is enabled by default... database queries may be performed during view rendering" WARN 로그를 출력한다 | [Spring Boot — JpaBaseConfiguration WARN log] "spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning." | `official-vendor-doc` | Spring Boot + Spring Data JPA 환경 | Spring Boot 가 future version 에서 default 를 false 로 변경할 계획이라는 뜻은 아님 — WARN 출력 자체만 보장 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `OSIV-AP-C1` ~ `C3`: Vlad Mihalcea 가 제시한 OSIV anti-pattern 의 3가지 근거 (connection 점유 / auto-commit / transaction boundary 우회). **단, 이는 Hibernate developer advocate 의 권위 있는 blog 의견이며 Hibernate 또는 Spring 공식 문서의 공식적인 "anti-pattern 선언" 이 아님** + - `OSIV-AP-C4`: Spring Boot 가 OSIV default true 임을 인정하고 WARN 로그로 명시한다는 사실 (공식 vendor 코드 base 의 verbatim WARN) +- **이 자료가 증명하지 않는 것**: + - Hibernate ORM User Guide 자체가 OSIV 를 anti-pattern 으로 명시적으로 deprecate 했다는 사실 (본 세션에서는 hibernate.org WebFetch denied — 직접 verbatim quote 미확보) + - OSIV on 으로 운영해도 안전한 워크로드의 정확한 조건 (예: low traffic, read-only) 은 본 인용 범위 밖 + - n+1 silent 문제가 OSIV 의 직접 효과인지 (n+1 은 OSIV 와 무관하게도 발생 가능 — OSIV 는 단지 silent 화) +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 의 `spring.jpa.open-in-view=false` 설정이 실제로 startup assertion 으로 들어가 있는지 코드 검증 + - 우리 service layer 가 fetch graph (`@EntityGraph` / `JOIN FETCH` / DTO projection) 를 일관성 있게 적용 중인지 코드 검증 + - vladmihalcea.com 의 원문을 다음 세션에서 정확하게 verbatim 으로 재확인 (본 세션 WebFetch 차단) + - Hibernate User Guide 의 OSIV 관련 직접 인용을 후속 라운드에 확보 (현재는 frontmatter URL 만 있음) + +## 메모 / Notes (내 프로젝트 해석 — 검증 전 추론) + +> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석. + +- **왜 anti-pattern 인가 (해석 정리)**: + 1. **connection pool 고갈** (`OSIV-AP-C2` 의 해석) — view rendering 동안 connection 점유. p99 latency 늘어남. + 2. **n+1 silent** (Vlad 본문 추가 해석) — service 에서 fetch 안 한 association 이 view 에서 lazy load → SQL 폭증을 service 단위 테스트에서 못 잡음. + 3. **transaction boundary 모호** (`OSIV-AP-C3`) — 추가 SQL 이 auto-commit 으로 새 단위로 나감. +- **ca-tmpl 결정과의 정합성**: "presentation 에서 DB 접근이 발생하면 계약 위반" 은 OSIV 끄고 service layer 에서 fetch graph 를 명시하라는 동일한 주장. +- **대안 (해석)**: + - `@EntityGraph` / explicit `JOIN FETCH` 로 service 에서 lazy association 을 미리 로드 + - DTO projection (interface/class projection) 으로 presentation 에서 entity 를 안 쓰게 +- **시사점**: Spring Boot 기본값이 `true` 라서 (`OSIV-AP-C4`) **명시적으로 `spring.jpa.open-in-view=false` 를 설정** 해야 함. ca-tmpl baseline 에 startup assertion 후보. + +## Related / 관련 + +- 같은 주제 다른 official-doc / company-tech-blog: + - Hibernate User Guide §Transactions (frontmatter URL — 본 세션 verbatim 미확보) + - Spring Boot reference (별도 raw 후속 수집 권장 — `spring.jpa.open-in-view` 공식 property doc) +- 인용하는 branch: + - [[raw/branch-notes/feature-persistence-failure-baseline]] + - [[raw/branch-notes/feature-architecture-enforcement-rules]] +- 인용하는 wiki: (미작성 — `/ingest` 시 `wiki/concepts/osiv-anti-pattern` 후보) +- 대안 그룹 (ca-tmpl 결정 컨텍스트): **Group G-C — Persistence failure** (OSIV off vs OSIV on vs DTO projection 강제) diff --git a/vault/20-evidence/official-docs/persistence-r2dbc-reactive-spring.md b/vault/20-evidence/official-docs/persistence-r2dbc-reactive-spring.md new file mode 100644 index 0000000..50f94f1 --- /dev/null +++ b/vault/20-evidence/official-docs/persistence-r2dbc-reactive-spring.md @@ -0,0 +1,104 @@ +--- +title: R2DBC — Reactive Relational Database Connectivity (r2dbc.io + Spring Data R2DBC) +source_type: official-doc +status: raw +confidence: medium +url: https://r2dbc.io/ +archive_url: +tags: [ca-persistence-failure, r2dbc, reactive, alternative, official-doc] +related_branches: [feature-persistence-failure-baseline] +related_projects: [ca-skeleton-operational-contract] +created: 2026-05-22 +last_reviewed: 2026-05-27 +--- + +# R2DBC — Reactive Relational Database Connectivity + +> Layer: `raw/official-docs/` — R2DBC 공식 사이트 + Spring Data R2DBC reference 발췌. ca-tmpl persistence baseline 의 **반례 (대안 2)** — Hikari + JDBC blocking 결정의 alternative. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-persistence-failure-baseline]] | "JPA + JDBC + Hikari blocking" baseline 결정의 alternative 비교 — R2DBC 가 어떤 trade-off 를 가지는지의 반례 | + +특정 branch 없이 foundational 조사로 수집한 경우: + +- [[raw/project-notes/ca-skeleton-operational-contract]] — ca-tmpl persistence stack 의 alternative 조사 + +## 컨텍스트 / 왜 저장했는지 + +ca-tmpl persistence baseline 의 **대안 후보**. "JPA + JDBC + Hikari blocking" 결정의 반례. R2DBC 를 택했을 때의 보안 / 운영 / debugging 차이를 비교 자료로 보관. + +## 출처 / Source + +- 원본 URL: https://r2dbc.io/ +- 보조 URL: https://docs.spring.io/spring-data/relational/reference/r2dbc.html (Spring Data R2DBC reference 랜딩) +- 보조 URL: https://docs.spring.io/spring-data/relational/reference/r2dbc/transactionality.html (transactionality 페이지 — 404 응답, URL 후속 재확인 필요) +- 아카이브 URL: (미수집) +- 저자 / 조직: R2DBC 워킹 그룹 (Pivotal/VMware 주도, 다수 driver 벤더 참여); Spring Data R2DBC = Spring 공식 +- 발행일: rolling (R2DBC 1.0 GA + Spring Data R2DBC 3.x current) +- 마지막 확인일: 2026-05-27 (WebFetch 검증: r2dbc.io 본문 verbatim 확보, Spring Data R2DBC reference 일부 verbatim 확보) +- 보조 자료: Oleh Dokuka, "Reactor 3 + R2DBC limitations" 발표 노트 (별도 raw 미수집) + +## 핵심 인용 / Key quotes (verbatim) + +> [r2dbc.io §In a Nutshell] "R2DBC is an open specification and establishes a Service Provider Interface (SPI) for driver vendors to implement and clients to consume." + +> [r2dbc.io §Relational Meets Reactive] "R2DBC is a specification designed from the ground up for reactive programming with SQL databases." + +> [r2dbc.io §Relational Meets Reactive] "It defines a non-blocking SPI for database driver implementors and client library authors." + +> [Spring Data R2DBC reference §Connecting to a Relational Database — `AbstractR2dbcConfiguration`] "As compared to registering a `ConnectionFactory` instance directly, the configuration support has the added advantage of also providing the container with an `ExceptionTranslator` implementation that translates R2DBC exceptions to exceptions in Spring's portable `DataAccessException` hierarchy for data access classes annotated with the `@Repository` annotation." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| R2DBC-C1 | R2DBC 는 open specification 이며, driver vendor 가 구현하고 client 가 consume 하는 SPI 정의 | [r2dbc.io §In a Nutshell] "R2DBC is an open specification and establishes a Service Provider Interface (SPI) for driver vendors to implement and clients to consume." | `official-standard` | SQL DB reactive driver 생태계 일반 | "JDBC 대체 표준" 같은 위계 비교 주장은 본 인용 범위 밖 — JDBC 와 공존 | +| R2DBC-C2 | R2DBC 는 reactive programming + SQL DB 를 위해 ground up 으로 설계 | [r2dbc.io §Relational Meets Reactive] "R2DBC is a specification designed from the ground up for reactive programming with SQL databases." | `official-standard` | reactive (Reactor / RxJava) + relational DB 사용 환경 | NoSQL 또는 messaging 시스템에 적용된다는 뜻 아님 | +| R2DBC-C3 | R2DBC 의 SPI 는 non-blocking 이며 driver implementor 와 client library 작성자 양쪽을 대상 | [r2dbc.io §Relational Meets Reactive] "It defines a non-blocking SPI for database driver implementors and client library authors." | `official-standard` | R2DBC driver / client library 구현 | "fully async at OS level" 같은 강한 주장은 본 인용 범위 밖 — SPI 가 non-blocking 이라는 것과 OS-level async 는 별개 | +| R2DBC-C4 | Spring Data R2DBC 는 `AbstractR2dbcConfiguration` 사용 시 `ExceptionTranslator` 를 컨테이너에 등록하여 R2DBC exception 을 Spring 의 portable `DataAccessException` hierarchy 로 변환 (`@Repository` 가 붙은 클래스 대상) | [Spring Data R2DBC reference] "...providing the container with an `ExceptionTranslator` implementation that translates R2DBC exceptions to exceptions in Spring's portable `DataAccessException` hierarchy for data access classes annotated with the `@Repository` annotation." | `official-vendor-doc` | Spring Data R2DBC + `@Repository` + `AbstractR2dbcConfiguration` 사용 시 | `R2dbcExceptionTranslator` 라는 정확한 클래스명이 본 인용에 등장하지 않음 — 구체 구현 클래스명은 javadoc 별도 확인 필요. 또한 `ConnectionFactory` 를 직접 등록하면 자동 적용되지 않음 (조건부) | +| R2DBC-C5 | R2DBC 는 JPA 를 지원하지 않으며, entity manager / lazy loading / first-level cache 가 없고 mapping 은 row-to-object 만 | (원본 frontmatter 발췌 — 본 세션 WebFetch 로 verbatim 직접 재확인 미완료. r2dbc.io 본문에 직접 등장하지 않음, Spring Data R2DBC reference 랜딩에도 등장하지 않음) | `needs-confirmation` | Spring Data R2DBC vs Spring Data JPA 비교 | 본 세션에서 직접 verbatim source 미확보 — 후속 라운드에 Spring Data R2DBC 의 "What is R2DBC" 또는 비교 페이지에서 verbatim 재확인 필요 | +| R2DBC-C6 | Transaction context 는 `ThreadLocal` 이 아닌 `reactor.util.context.Context` 로 전파되며, `@Transactional` 은 `TransactionalOperator` / reactive transaction manager 를 통해 동작 | (원본 frontmatter 발췌 — 본 세션에서 transactionality 페이지 404. r2dbc.io 와 Spring Data R2DBC 랜딩에는 등장하지 않음) | `needs-confirmation` | reactive Spring + `@Transactional` 사용 환경 | 본 세션 WebFetch 로 verbatim 미확보 — Spring Framework reference 의 transaction propagation 섹션 또는 Spring Data R2DBC transactionality 페이지의 정확한 URL 후속 확인 필요 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `R2DBC-C1` ~ `C3`: R2DBC 가 reactive SQL DB 를 위한 non-blocking SPI 의 open specification 이라는 사실 (r2dbc.io 공식) + - `R2DBC-C4`: Spring Data R2DBC 가 `DataAccessException` hierarchy 로 exception 을 변환한다는 사실 → ca-tmpl 의 SQLState matrix 가 R2DBC 환경에서도 일부 재사용 가능 +- **이 자료가 증명하지 않는 것**: + - R2DBC 가 JDBC 보다 "더 빠르다" 또는 "더 적은 자원을 쓴다" 는 정량 주장 (specific 워크로드 의존, 본 자료 범위 밖) + - JPA 와의 정확한 feature gap (`R2DBC-C5` 의 entity manager / lazy loading 부재 주장은 본 세션에서 verbatim 미확보 — `needs-confirmation`) + - reactive transaction propagation 의 정확한 메커니즘 (`R2DBC-C6` 도 `needs-confirmation`) + - Hikari `getThreadsAwaitingConnection()` 와 동등한 R2DBC pool metric 이름 (`r2dbc.pool.acquired` 등) — 별도 자료 (R2DBC Pool 또는 Micrometer 통합 문서) 필요 +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 이 실제로 R2DBC 를 고려할 워크로드인지 (high-fan-in API gateway 시나리오 여부) + - Flyway/Liquibase 등 blocking migration 도구와의 thread 정책 분리 절차 + - reactive stack 도입 시 onboarding 비용 (stack trace 가 reactor operator chain 형태) + - `R2DBC-C5` / `C6` 의 verbatim 출처 후속 확보 + +## 메모 / Notes (내 프로젝트 해석 — 검증 전 추론) + +> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석. + +- **장점 (해석)**: + - connection 개수 << thread 개수. high-fan-in API gateway 에서 Hikari + JPA 보다 자원 효율 (정성적) + - backpressure: stream 결과를 lazy 하게 가져옴 +- **단점 (ca-tmpl 입장 — 해석)**: + - JPA 생태계 손실 — `@OneToMany`, lazy loading, dirty checking, criteria, JPQL 없음. native query + manual mapping 이 기본 (`R2DBC-C5` — 단, verbatim 후속 확인 필요) + - **debugging cost** — stack trace 가 reactor operator chain. 신입/주니어 onboarding 부담 + - blocking JDBC libraries (Flyway/Liquibase migration, JdbcTemplate) 와 혼용 시 thread 정책 분리 필요 + - exception hierarchy 는 동일(`DataAccessException`)이라 SQLState matrix 재사용 가능 (`R2DBC-C4`) — 하지만 timeout 정책이 reactor `timeout()` operator 로 이동 +- **시사점**: ca-tmpl 이 **JPA + JDBC blocking 을 baseline 으로 둔 이유** 의 반대편. high-throughput / low-resource API 에서만 정당화. dirty checking 의존도가 높은 도메인이면 도입 비용이 큼. +- **운영 차이 (해석, 별도 metric 자료 필요)**: Hikari `getThreadsAwaitingConnection()` 대신 connection factory 별 `r2dbc.pool.acquired`, `r2dbc.pool.pending`, `r2dbc.pool.max.allocated` metric 후보 — R2DBC Pool 문서 별도 확인 필요. + +## Related / 관련 + +- 같은 주제 다른 official-doc / company-tech-blog: + - [[raw/official-docs/persistence-spring-dataaccessexception-hierarchy]] (`DataAccessException` hierarchy — R2DBC 와 공유) + - [[raw/official-docs/persistence-hikaricp-pool-sizing-wiki]] (blocking JDBC alternative) +- 인용하는 branch: + - [[raw/branch-notes/feature-persistence-failure-baseline]] +- 인용하는 wiki: (미작성) +- 대안 그룹 (ca-tmpl 결정 컨텍스트): **Group G-C — Persistence failure** (대안 1: Spring Data JPA blocking [ca-tmpl 채택] / 대안 2: R2DBC reactive / 대안 3: JOOQ SQL-first / 대안 4: 직접 JDBC + 자체 classifier) diff --git a/vault/20-evidence/official-docs/persistence-spring-dataaccessexception-hierarchy.md b/vault/20-evidence/official-docs/persistence-spring-dataaccessexception-hierarchy.md new file mode 100644 index 0000000..63c22ec --- /dev/null +++ b/vault/20-evidence/official-docs/persistence-spring-dataaccessexception-hierarchy.md @@ -0,0 +1,103 @@ +--- +title: Spring DataAccessException hierarchy & exception translation (공식 문서 + Javadoc) +source_type: official-doc +status: raw +confidence: high +url: https://docs.spring.io/spring-framework/reference/data-access/dao.html +archive_url: +tags: [ca-persistence-failure, spring, jdbc, jpa, exception-translation, official-doc] +related_branches: [feature-persistence-failure-baseline, feature-operational-error-observability-foundation] +related_projects: [ca-skeleton-operational-contract] +created: 2026-05-22 +last_reviewed: 2026-05-27 +--- + +# Spring DataAccessException hierarchy & exception translation + +> Layer: `raw/official-docs/` — Spring Framework Reference + `DataAccessException` Javadoc 발췌. ca-tmpl persistence failure 분류의 **공식 backbone**. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-persistence-failure-baseline]] | ca-tmpl SQLState 9-row matrix 가 임의 분류가 아니라 Spring 의 `DataAccessException` hierarchy 위에 SQLState 를 입힌 형태라는 사실 근거 | +| [[raw/branch-notes/feature-operational-error-observability-foundation]] | error code → retryable / non-retryable / recoverable 의 3-way classifier 가 Spring 공식 hierarchy 와 정합한다는 근거 | + +특정 branch 없이 foundational 조사로 수집한 경우: + +- [[raw/project-notes/ca-skeleton-operational-contract]] — ca-tmpl persistence failure baseline + error observability 의 초기 조사 + +## 컨텍스트 / 왜 저장했는지 + +ca-tmpl persistence failure 분류의 **공식 기준**. SQLState 9-row matrix 가 임의 분류가 아니라 Spring 이 이미 채택한 hierarchy (`DataAccessException` 하위) 를 따른다는 근거. + +## 출처 / Source + +- 원본 URL: https://docs.spring.io/spring-framework/reference/data-access/dao.html +- 보조 URL: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/dao/DataAccessException.html (Javadoc — `Direct Known Subclasses` 확정) +- 아카이브 URL: (미수집) +- 저자 / 조직: Spring Team (VMware/Broadcom) +- 발행일: rolling (Spring Framework current) +- 마지막 확인일: 2026-05-27 (WebFetch 검증: dao.html landing 의 high-level translation quote + Javadoc 의 Direct Known Subclasses 확보. `sql-error-codes.xml` 및 상세 subclass 그룹 quote 는 본 세션 verbatim 미확보 — Javadoc 으로 보강) +- 보조 자료: `SQLExceptionTranslator`, `SQLErrorCodeSQLExceptionTranslator` Javadoc (별도 raw 미수집) + +## 핵심 인용 / Key quotes (verbatim) + +> [Spring Framework Reference §Consistent Exception Hierarchy] "Spring provides a convenient translation from technology-specific exceptions, such as `SQLException` to its own exception class hierarchy, which has `DataAccessException` as the root exception. These exceptions wrap the original exception so that there is never any risk that you might lose any information about what might have gone wrong." + +> [Spring Framework Reference §Consistent Exception Hierarchy] "In addition to JDBC exceptions, Spring can also wrap JPA- and Hibernate-specific exceptions, converting them to a set of focused runtime exceptions." + +> [`DataAccessException` Javadoc — class description] "Root of the hierarchy of data access exceptions discussed in Expert One-On-One J2EE Design and Development. ... This exception hierarchy aims to let user code find and handle the kind of error encountered without knowing the details of the particular data access API in use (for example, JDBC). Thus, it is possible to react to an optimistic locking failure without knowing that JDBC is being used. As this class is a runtime exception, there is no need for user code to catch it or subclasses if any error is to be considered fatal (the usual case)." + +> [`DataAccessException` Javadoc — Direct Known Subclasses] "`NonTransientDataAccessException`, `RecoverableDataAccessException`, `ScriptException` (org.springframework.jdbc.datasource.init), `ScriptException` (org.springframework.r2dbc.connection.init), `TransientDataAccessException`" + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| SDA-EX-C1 | Spring 은 `SQLException` 같은 technology-specific exception 을 `DataAccessException` 을 root 로 하는 자체 hierarchy 로 변환하며, 원본 exception 정보를 wrap 으로 보존 | [Reference §Consistent Exception Hierarchy] "Spring provides a convenient translation from technology-specific exceptions, such as `SQLException` to its own exception class hierarchy, which has `DataAccessException` as the root exception. These exceptions wrap the original exception so that there is never any risk that you might lose any information about what might have gone wrong." | `official-vendor-doc` | Spring JDBC / Spring Data JPA / Spring Data R2DBC 사용 환경 | "모든 vendor exception 이 100% 손실 없이 매핑된다" 는 강한 주장은 아님 — wrap 으로 보존되지만 변환 표는 `sql-error-codes.xml` 의 한계 안에서 동작 | +| SDA-EX-C2 | `DataAccessException` 은 unchecked runtime exception 이며, user code 가 catch 할 필요가 없음 (fatal 처리 default 가정) | [Javadoc] "As this class is a runtime exception, there is no need for user code to catch it or subclasses if any error is to be considered fatal (the usual case)." | `official-reference` | DAO 호출 측 코드 일반 | "절대 catch 하지 말라" 는 뜻 아님 — retry 가능한 transient 류는 의도적으로 catch 하는 것이 ca-tmpl 의 retry 정책과 정합 | +| SDA-EX-C3 | `DataAccessException` 의 **Direct Known Subclasses** 는 `NonTransientDataAccessException`, `RecoverableDataAccessException`, `TransientDataAccessException` (그리고 init 패키지의 `ScriptException` 2종). 즉 top-level 3-way 분류: transient / non-transient / recoverable | [Javadoc — Direct Known Subclasses] "NonTransientDataAccessException, RecoverableDataAccessException, ScriptException (org.springframework.jdbc.datasource.init), ScriptException (org.springframework.r2dbc.connection.init), TransientDataAccessException" | `official-reference` | Spring DAO hierarchy 분류 일반 | 각 sub-tree (`QueryTimeoutException`, `ConcurrencyFailureException` 등) 의 정확한 부모는 별도 Javadoc 확인 필요 (본 인용은 Direct Known Subclasses 만 보장) | +| SDA-EX-C4 | Spring 은 JDBC exception 외에도 JPA / Hibernate 의 vendor-specific exception 을 별도 runtime exception 집합으로 변환 | [Reference §Consistent Exception Hierarchy] "In addition to JDBC exceptions, Spring can also wrap JPA- and Hibernate-specific exceptions, converting them to a set of focused runtime exceptions." | `official-vendor-doc` | Spring Data JPA + Hibernate 사용 환경 | "어떤 Hibernate exception 이 어떤 Spring exception 으로 매핑되는지" 의 정확한 표는 본 인용 범위 밖 — `HibernateJpaDialect` 별도 | +| SDA-EX-C5 | hierarchy 의 의도: user code 가 vendor (JDBC 등) 디테일을 모르고도 error kind 별로 핸들링 가능 (예: optimistic locking failure 를 JDBC 사용 여부 무관하게 처리) | [Javadoc] "This exception hierarchy aims to let user code find and handle the kind of error encountered without knowing the details of the particular data access API in use (for example, JDBC). Thus, it is possible to react to an optimistic locking failure without knowing that JDBC is being used." | `official-reference` | DAO portability / handler 분리 | "모든 사용자 코드가 vendor-agnostic 해야 한다" 는 prescriptive 주장 아님 — 가능성을 의도한다는 뜻 | +| SDA-EX-C6 | `sql-error-codes.xml` 의 error code mapping 을 통해 vendor-specific SQL error 가 Spring DAO hierarchy 로 매핑된다는 메커니즘 | (원본 frontmatter 발췌 — 본 세션 WebFetch 로 verbatim 직접 재확인 미완료. dao.html landing 에는 등장하지 않음, javadoc 별도 확인 필요) | `needs-confirmation` | `SQLErrorCodeSQLExceptionTranslator` 사용 환경 | 본 세션 verbatim 미확보 — 후속 라운드에 `SQLErrorCodeSQLExceptionTranslator` Javadoc 또는 Reference 의 JDBC 섹션에서 verbatim 재확인 필요 | +| SDA-EX-C7 | SQLState 8\* (connection 계열) / 40001 (serialization) / 40P01 (deadlock) / 23\* (integrity) / 23505 (unique violation) 와 Spring exception class 간의 구체적 매핑 (`DataAccessResourceFailureException`, `ConcurrencyFailureException` 계열, `DataIntegrityViolationException`, `DuplicateKeyException`) | (원본 frontmatter 발췌 — 본 세션 dao.html landing 에 등장하지 않음. `sql-error-codes.xml` source 또는 vendor-specific Javadoc 별도 확인 필요) | `needs-confirmation` | PostgreSQL / vendor 환경에서의 ca-tmpl SQLState matrix 정당성 | 본 세션 verbatim 미확보 — ca-tmpl 9-row matrix 의 SQLState ↔ Spring class 매핑은 후속 라운드에 vendor 별 `sql-error-codes.xml` 로 직접 검증 필요 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `SDA-EX-C1` ~ `C5`: Spring 의 `DataAccessException` hierarchy 가 존재하며 vendor exception 을 변환한다는 사실, hierarchy 가 unchecked 이며 portability 를 의도한다는 사실, top-level 3-way 분류 (`Transient` / `NonTransient` / `Recoverable`) 의 존재 +- **이 자료가 증명하지 않는 것**: + - `sql-error-codes.xml` 의 정확한 매핑 표 (`SDA-EX-C6` — `needs-confirmation`) + - 특정 SQLState (8\*, 23\*, 40001, 23505 등) 가 어떤 Spring exception 으로 매핑되는지의 vendor-별 표 (`SDA-EX-C7` — `needs-confirmation`). ca-tmpl 9-row matrix 의 vendor 정당성은 별도 검증 필요 + - 각 sub-tree (`QueryTimeoutException`, `OptimisticLockingFailureException` 등) 의 직접 부모가 `TransientDataAccessException` 인지 `RecoverableDataAccessException` 인지의 정확한 위계 — Javadoc 별도 확인 필요 +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 9-row matrix 의 SQLState → ca-tmpl code 매핑이 Spring 공식 `sql-error-codes.xml` 의 PostgreSQL/MySQL section 과 일치하는지 코드 검증 + - `DB_UNIQUE_VIOLATION` 을 별도 code 로 가져가는 결정이 `DuplicateKeyException` 의 위계 (구체 부모는 `DataIntegrityViolationException`) 와 정합한지 javadoc 확인 + - JPA / Hibernate exception 매핑이 ca-tmpl 의 `retryable` 분류와 충돌하지 않는지 별도 검증 + +## 메모 / Notes (내 프로젝트 해석 — 검증 전 추론) + +> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석. + +- **핵심 의미 (해석)**: + - `TransientDataAccessException` = retry 로 회복 가능 → ca-tmpl `retryable=true` 후보 + - `NonTransientDataAccessException` = retry 무의미 → ca-tmpl `retryable=false` 후보 + - `RecoverableDataAccessException` = 환경 정상화 후 재시도 가능 (커넥션 재획득 등) +- **SQLState 매핑 (해석 — `SDA-EX-C7` 의 needs-confirmation 영역)**: + - SQLState 8\* 는 connection 계열 → `DataAccessResourceFailureException` 으로 매핑된다는 통설. ca-tmpl `DB_UNAVAILABLE` 매핑과 일치한다는 가정 + - SQLState 40001(serialization), 40P01(deadlock) → `ConcurrencyFailureException` 계열. ca-tmpl `DB_SERIALIZATION_FAILURE`, `DB_DEADLOCK` 와 일치한다는 가정 + - SQLState 23\* → `DataIntegrityViolationException`. ca-tmpl `DATA_INTEGRITY` family 가정 + - 23505 unique violation 은 `DuplicateKeyException` 으로 더 specific 함 → ca-tmpl 이 별도 code `DB_UNIQUE_VIOLATION` 로 가져가는 근거 +- **시사점**: ca-tmpl 9-row matrix 는 **자의적 분류가 아니라** Spring DAO hierarchy 의 3-way 분류 (`SDA-EX-C3`) 에 SQLState 를 입힌 형태. canonical 로 승급 시 인용 가능 — 단 vendor 매핑은 `sql-error-codes.xml` 로 보강 필요. + +## Related / 관련 + +- 같은 주제 다른 official-doc / company-tech-blog: + - [[raw/official-docs/persistence-r2dbc-reactive-spring]] (R2DBC 도 동일 `DataAccessException` hierarchy 재사용) + - [[raw/official-docs/persistence-osiv-antipattern-hibernate-vladmihalcea]] (JPA / Hibernate exception 변환 컨텍스트) +- 인용하는 branch: + - [[raw/branch-notes/feature-persistence-failure-baseline]] + - [[raw/branch-notes/feature-operational-error-observability-foundation]] +- 인용하는 wiki: (미작성) +- 대안 그룹 (ca-tmpl 결정 컨텍스트): **Group G-C — Persistence failure** (대안: Spring DAO hierarchy [ca-tmpl 채택] / R2DBC reactive / JOOQ SQL-first / 직접 JDBC + 자체 classifier / DB-specific vendor classification) diff --git a/vault/20-evidence/official-docs/postgres-transaction-isolation-official.md b/vault/20-evidence/official-docs/postgres-transaction-isolation-official.md new file mode 100644 index 0000000..4a71e12 --- /dev/null +++ b/vault/20-evidence/official-docs/postgres-transaction-isolation-official.md @@ -0,0 +1,98 @@ +--- +title: "official-doc / PostgreSQL Transaction Isolation — MVCC 격리 수준 보장 공식 레퍼런스" +source_type: official-doc +url: https://www.postgresql.org/docs/current/transaction-iso.html +archive_url: +vendor: PostgreSQL Global Development Group +related_branches: [feature-transaction-concurrency-contract] +related_projects: [ca-skeleton] +tags: [official-doc, ca-skeleton, persistence, postgresql, transaction-isolation, mvcc] +created: 2026-06-09 +--- + +# official-doc / PostgreSQL Transaction Isolation — MVCC 격리 수준 보장 공식 레퍼런스 + +> Layer: `raw/official-docs/` — PostgreSQL 공식 문서의 트랜잭션 격리 수준(READ COMMITTED / REPEATABLE READ / SERIALIZABLE) 보장 범위 원문 발췌. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 별도 작성. 원본은 raw에 영구 보관. + +## Parent / 활용 branch + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-transaction-concurrency-contract]] | ca-tmpl TransactionPort 가 ISOLATION_READ_COMMITTED 를 기본값으로 채택하고 REPEATABLE_READ/SERIALIZABLE 을 명시 opt-in 으로 예약한 근거 (D3). PostgreSQL MVCC snapshot semantics, dirty/non-repeatable/phantom read 방지 범위, 직렬화 실패 에러를 vendor SSOT 로 확보. | + +## 출처 / Source + +- 원본 URL: https://www.postgresql.org/docs/current/transaction-iso.html +- 아카이브 URL: (미수집) +- 저자 / 조직: PostgreSQL Global Development Group +- 발행일: PostgreSQL 18 Documentation (current) +- 마지막 확인일: 2026-06-09 + +## 왜 저장했는지 / Why archived + +`feature-transaction-concurrency-contract` D3 결정("isolation level default = READ_COMMITTED, PostgreSQL/MySQL 양쪽 동일 의미") 이 `UNSUPPORTED_DECISION` 으로 라벨된 상태였다. 이 페이지는 PostgreSQL vendor SSOT 로서 READ COMMITTED / REPEATABLE READ / SERIALIZABLE 의 정확한 보장 범위(MVCC snapshot 단위, 허용되지 않는 현상, 직렬화 실패 에러 메시지)를 verbatim 으로 제공한다. + +## 핵심 인용 / Key quotes (verbatim, 5문장) + +> [§13.2.1] "Read Committed is the default isolation level in PostgreSQL. When a transaction uses this isolation level, a SELECT query (without a FOR UPDATE/SHARE clause) sees only data committed before the query began; it never sees either uncommitted data or changes committed by concurrent transactions during the query's execution. In effect, a SELECT query sees a snapshot of the database as of the instant the query begins to run." +> — 위치: §13.2.1 Read Committed Isolation Level, line 29 in fetched text + +> [§13.2.1] "a SELECT query sees a snapshot of the database as of the instant the query begins to run." +> — 위치: §13.2.1, line 29 (statement-level snapshot 핵심 문장) + +> [§13.2.2] "a query in a repeatable read transaction sees a snapshot as of the start of the first non-transaction-control statement in the transaction, not as of the start of the current statement within the transaction. Thus, successive SELECT commands within a single transaction see the same data, i.e., they do not see changes made by other transactions that committed after their own transaction started." +> — 위치: §13.2.2 Repeatable Read Isolation Level, line 41 in fetched text + +> [§13.2.2] "ERROR: could not serialize access due to concurrent update" +> — 위치: §13.2.2, line 47 (REPEATABLE READ 충돌 시 반환되는 실제 에러 메시지) + +> [§13.2.3] "The Serializable isolation level provides the strictest transaction isolation. This level emulates serial transaction execution for all committed transactions; as if transactions had been executed one after another, serially, rather than concurrently. However, like the Repeatable Read level, applications using this level must be prepared to retry transactions due to serialization failures. In fact, this isolation level works exactly the same as Repeatable Read except that it also monitors for conditions which could make execution of a concurrent set of serializable transactions behave in a manner inconsistent with all possible serial (one at a time) executions of those transactions. This monitoring does not introduce any blocking beyond that present in repeatable read, but there is some overhead to the monitoring, and detection of the conditions which could cause a serialization anomaly will trigger a serialization failure." +> — 위치: §13.2.3 Serializable Isolation Level, line 59 in fetched text + +> [§13.2 intro] "In PostgreSQL, you can request any of the four standard transaction isolation levels, but internally only three distinct isolation levels are implemented, i.e., PostgreSQL's Read Uncommitted mode behaves like Read Committed. This is because it is the only sensible way to map the standard isolation levels to PostgreSQL's multiversion concurrency control architecture." +> — 위치: §13.2 Transaction Isolation, line 21 in fetched text + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| PG-ISO-C1 | PostgreSQL 의 기본 격리 수준은 READ COMMITTED 이다 | [§13.2.1] "Read Committed is the default isolation level in PostgreSQL." | `official-vendor-doc` | PostgreSQL (모든 현행 버전) | MySQL InnoDB 의 기본 격리 수준 (별도 확인 필요). Spring `@Transactional` 의 기본 isolation 설정값 (Spring default = DEFAULT, 즉 vendor 위임) | +| PG-ISO-C2 | READ COMMITTED 에서 SELECT 는 문장 시작 시점의 스냅샷을 사용한다 (statement-level snapshot) | [§13.2.1] "a SELECT query sees a snapshot of the database as of the instant the query begins to run." | `official-vendor-doc` | PostgreSQL READ COMMITTED isolation level | 동일 트랜잭션 내 두 번째 SELECT 가 같은 데이터를 본다는 보장 — READ COMMITTED 에서는 각 문장마다 새 스냅샷 (non-repeatable read 허용) | +| PG-ISO-C3 | REPEATABLE READ 에서 SELECT 는 트랜잭션 시작 시점의 스냅샷을 사용한다 (transaction-level snapshot). 동일 트랜잭션 내 연속 SELECT 는 같은 데이터를 본다 | [§13.2.2] "a query in a repeatable read transaction sees a snapshot as of the start of the first non-transaction-control statement in the transaction, not as of the start of the current statement within the transaction. Thus, successive SELECT commands within a single transaction see the same data, i.e., they do not see changes made by other transactions that committed after their own transaction started." | `official-vendor-doc` | PostgreSQL REPEATABLE READ isolation level | MySQL InnoDB REPEATABLE READ 동작 (PostgreSQL 과 다를 수 있음 — consistent read 의 차이). 분산 트랜잭션 환경에서의 동일 보장 | +| PG-ISO-C4 | REPEATABLE READ 트랜잭션이 다른 트랜잭션이 변경한 행을 수정하려 하면 `ERROR: could not serialize access due to concurrent update` 에러로 롤백된다 | [§13.2.2] "ERROR: could not serialize access due to concurrent update" | `official-vendor-doc` | PostgreSQL REPEATABLE READ write 충돌 시나리오 | 이 에러가 Spring `OptimisticLockingFailureException` 으로 자동 변환된다는 보장 (Spring Data 예외 변환 계층 별도 확인 필요) | +| PG-ISO-C5 | SERIALIZABLE 은 동시 트랜잭션 집합이 직렬 실행과 동일한 결과를 생성하지 않을 조건을 감지 시 serialization failure 를 발생시킨다. 직렬화 이상 발생 시 반환 에러: `ERROR: could not serialize access due to read/write dependencies among transactions` | [§13.2.3] "The Serializable isolation level provides the strictest transaction isolation. [...] detection of the conditions which could cause a serialization anomaly will trigger a serialization failure." | `official-vendor-doc` | PostgreSQL SERIALIZABLE isolation level | SERIALIZABLE 을 사용하는 모든 use case 가 재시도 없이 성공한다는 보장. 모니터링 오버헤드 규모 (측정값 미제공) | +| PG-ISO-C6 | PostgreSQL 은 내부적으로 세 가지 격리 수준만 구현한다. READ UNCOMMITTED 는 READ COMMITTED 와 동일하게 동작한다 | [§13.2 intro] "internally only three distinct isolation levels are implemented, i.e., PostgreSQL's Read Uncommitted mode behaves like Read Committed. This is because it is the only sensible way to map the standard isolation levels to PostgreSQL's multiversion concurrency control architecture." | `official-vendor-doc` | PostgreSQL MVCC 아키텍처 | MySQL / Oracle 등 다른 RDBMS 에서 동일하게 READ UNCOMMITTED 가 READ COMMITTED 로 동작한다는 보장 | + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `PG-ISO-C1`: PostgreSQL 의 기본 격리 수준이 READ COMMITTED 임 (D3 UNSUPPORTED_DECISION 해소 근거) + - `PG-ISO-C2`: READ COMMITTED 에서 SELECT 는 statement-level snapshot (각 문장마다 새 스냅샷) + - `PG-ISO-C3`: REPEATABLE READ 에서 SELECT 는 transaction-level snapshot (트랜잭션 시작 시점 고정) + - `PG-ISO-C4`: REPEATABLE READ write 충돌 시 구체적인 에러 메시지 + 롤백 동작 + - `PG-ISO-C5`: SERIALIZABLE 의 직렬화 이상 감지 + serialization failure 에러 메시지 + - `PG-ISO-C6`: PostgreSQL 내부적으로 3가지 격리 수준만 존재 (READ UNCOMMITTED = READ COMMITTED) + +- 이 자료가 증명하지 않는 것: + - MySQL InnoDB 의 READ COMMITTED 시맨틱이 PostgreSQL 과 동일하다는 것 (MySQL 별도 raw 수집 필요) + - Spring `@Transactional(isolation = Isolation.READ_COMMITTED)` 설정이 PostgreSQL 에서 이 시맨틱을 정확히 전달한다는 것 (Spring DataSource TransactionManager 동작 별도 확인 필요) + - REPEATABLE READ 충돌 에러(`PG-ISO-C4`)가 Spring Data 예외 변환 계층에서 `OptimisticLockingFailureException` 으로 변환된다는 것 + - 분산 트랜잭션(XA, Saga) 환경에서의 격리 보장 + +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - MySQL InnoDB 격리 수준 공식 문서 별도 raw 수집 (`https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html`) + - Spring `TransactionPort` 어댑터가 HikariCP + PostgreSQL 드라이버를 통해 격리 수준을 정확히 전달하는지 integration test 검증 (feature-transaction-concurrency-contract Claims To Verify 항목) + +## 메모 / Notes + +- D3 `UNSUPPORTED_DECISION` 해소: `PG-ISO-C1` 이 "READ COMMITTED 는 PostgreSQL 기본값" 을 verbatim 으로 증명. 단 MySQL InnoDB 쪽은 별도 raw 수집 전까지 여전히 `UNSUPPORTED_DECISION` 상태 유지. +- Table 13.1 (격리 수준 × 허용 현상 행렬): PostgreSQL 의 REPEATABLE READ 는 SQL 표준보다 강한 보장 제공 — phantom read 도 방지 (SQL 표준은 허용). 이 점이 MySQL InnoDB REPEATABLE READ (gap lock 기반 phantom read 방지) 와 구현 메커니즘은 다르지만 보장 결과는 유사함을 시사 — 단 verbatim 비교는 MySQL raw 수집 후 별도 검증 필요. +- SERIALIZABLE 구현: PostgreSQL 9.1+ 부터 Serializable Snapshot Isolation(SSI) 사용. 이전 버전은 REPEATABLE READ 와 동일 동작이었음 (문서 Note 참조). + +## Related / 관련 + +- MySQL InnoDB 격리 수준 (미수집): `https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html` +- Spring Framework TX isolation 설정: [[raw/official-docs/spring-tx-management-reference]] +- `@Transactional` 공식 문서: [[raw/official-docs/at-transactional-spring-official]] +- 이 자료를 인용한 wiki 요약: `[[wiki/concepts/transaction-isolation]]` (생성 시) diff --git a/vault/20-evidence/official-docs/postgresql-slow-query-log-official.md b/vault/20-evidence/official-docs/postgresql-slow-query-log-official.md new file mode 100644 index 0000000..5a5ce5b --- /dev/null +++ b/vault/20-evidence/official-docs/postgresql-slow-query-log-official.md @@ -0,0 +1,95 @@ +--- +title: official-doc / PostgreSQL log_min_duration_statement — Runtime Configuration for Logging +source_type: official-doc +url: https://www.postgresql.org/docs/current/runtime-config-logging.html +archive_url: +status: raw +confidence: high +tags: [backend, db, postgresql, observability, slow-query, dba] +related_branches: [feature-database-connection-pool-contract] +related_projects: [] +created: 2026-06-09 +last_reviewed: 2026-06-09 +--- + +# PostgreSQL log_min_duration_statement — Runtime Configuration for Logging + +> Layer: `raw/` — 외부 자료(공식 문서)의 원문 발췌·출처 기록. + +## Parent / 활용 branch + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-database-connection-pool-contract]] | DB 사이드 슬로우 쿼리 탐지 방식(DB 레이어)의 파라미터 노출 여부와 설정 메커니즘 근거 | + +## 출처 / Source + +- 원본 URL: https://www.postgresql.org/docs/current/runtime-config-logging.html +- 저자 / 조직: PostgreSQL Global Development Group (공식 문서) +- 마지막 확인일: 2026-06-09 + +## 왜 저장했는지 / Why archived + +`feature-database-connection-pool-contract` 브랜치에서 DB 사이드 슬로우 쿼리 탐지 대안으로 PostgreSQL `log_min_duration_statement` 를 검토. 핵심 질문: (1) 파라미터 값(바인드 변수)이 PostgreSQL 서버 로그에 출력되는가, (2) 이를 제어할 수 있는가, (3) 앱 사이드 vs DB 사이드 소유권 트레이드오프. + +## 핵심 인용 / Key quotes (verbatim) + +> "log_min_duration_statement (integer) — Logs the duration of each completed statement if it ran for at least the specified amount of time. For example, setting this to 250ms will cause all SQL statements that run 250ms or longer to be logged. Enabling this option can be helpful in tracking down unoptimized queries in your applications. Only superusers and users with the appropriate SET privilege can change this setting." + +— PostgreSQL docs, runtime-config-logging.html + +> "For clients using extended query protocol, durations of the Parse, Bind, and Execute steps are logged independently." + +— PostgreSQL docs, runtime-config-logging.html + +> "values of the Bind parameters are included (with any embedded single-quote marks doubled)" + +— PostgreSQL docs (log_statement 섹션, extended query protocol 에서 Bind 파라미터 포함 명시) + +> "log_parameter_max_length: Trims bind parameter values to specified bytes in non-error logs (default: -1 = full)" + +— PostgreSQL docs, runtime-config-logging.html + +> "Logged statements might reveal sensitive data and even contain plaintext passwords." + +— PostgreSQL docs (보안 경고) + +> "log_min_duration_sample (integer) — ... logs the same information as log_min_duration_statement but only for a subset ... Sample rate controlled by log_statement_sample_rate (floating point: 0.0 to 1.0)" + +— PostgreSQL docs (샘플링 기반 슬로우 쿼리 로깅) + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| C1 | PostgreSQL `log_min_duration_statement` 는 지정 임계값(ms) 이상 소요된 완료된 쿼리의 실행 시간을 로그에 기록한다 | "Logs the duration of each completed statement if it ran for at least the specified amount of time" | `official-standard` | PostgreSQL 12+ (extended query protocol 사용 환경) | MySQL 등 다른 DB에서도 동일하게 동작한다는 주장 반증 | +| C2 | Extended query protocol 사용 시 바인드 파라미터 값이 PostgreSQL 서버 로그에 포함된다 | "values of the Bind parameters are included (with any embedded single-quote marks doubled)" | `official-standard` | PostgreSQL + JDBC extended query protocol 환경 | 앱 로그에 파라미터가 노출된다는 주장 반증 (DB 서버 로그에만 기록) | +| C3 | `log_parameter_max_length` 로 서버 로그에 기록되는 파라미터 값의 길이를 제한할 수 있다 (기본값 -1 = 전체) | "log_parameter_max_length: Trims bind parameter values to specified bytes in non-error logs (default: -1 = full)" | `official-standard` | PostgreSQL 13+ | 파라미터 값 자체를 마스킹/제거한다는 주장 반증 (길이 제한만 가능) | +| C4 | PostgreSQL 공식 문서는 슬로우 쿼리 로그가 민감한 데이터와 평문 패스워드를 포함할 수 있다고 경고한다 | "Logged statements might reveal sensitive data and even contain plaintext passwords." | `official-standard` | PostgreSQL 모든 버전 | DB 로그가 앱 로그보다 안전하다는 주장 반증 (DBA 접근 권한 격리가 전제되어야 함) | +| C5 | `log_min_duration_sample` + `log_statement_sample_rate` 로 고트래픽 환경에서 샘플링 기반 슬로우 쿼리 탐지가 가능하다 | "logs the same information as log_min_duration_statement but only for a subset" | `official-standard` | PostgreSQL 13+ 고트래픽 환경 | — | +| C6 | `log_min_duration_statement` 설정은 postgresql.conf 또는 서버 커맨드라인에서만 가능하며, superuser 또는 SET 권한이 있는 사용자만 변경 가능하다 | "Only superusers and users with the appropriate SET privilege can change this setting" | `official-standard` | PostgreSQL 모든 버전 | 앱 코드에서 동적으로 임계값을 변경할 수 있다는 주장 반증 | + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `C1~C6`: PostgreSQL DB 사이드 슬로우 쿼리 로그의 동작, 파라미터 포함 여부, 제어 방법 +- 이 자료가 증명하지 않는 것: + - 앱 사이드 탐지 방식 (Hibernate, datasource-proxy 등)이 DB 사이드보다 열등하다는 주장 + - DB 사이드 탐지가 앱 사이드 파라미터 노출 문제를 해결한다는 주장 (DB 서버 로그에는 파라미터 노출, DBA 접근 통제 필요) + - MySQL `slow_query_log` 의 동작 방식 (별도 문서 필요) +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - 프로젝트가 PostgreSQL 을 사용하는지 MySQL 을 사용하는지 확인 + - DBA 팀의 PostgreSQL 서버 로그 접근 권한 정책 확인 + - JDBC URL 에 `prepareThreshold=0` 설정 시 extended query protocol 비활성화 여부 확인 (파라미터 노출 패턴 변경) + +## 메모 / Notes + +- PostgreSQL 서버 로그는 앱 로그와 분리된 스토리지에 기록되므로, DB 인프라팀(DBA)의 접근 권한 통제로 파라미터 노출 범위를 앱 개발팀과 격리 가능 +- 단 "파라미터가 DB 로그에 기록되지 않음" 과 "파라미터가 노출되지 않음" 은 다른 개념 — DBA 팀이 동일 보안 요구사항을 만족해야 함 +- `auto_explain` 모듈로 슬로우 쿼리의 실행 계획(EXPLAIN)도 자동 기록 가능 + +## Related / 관련 + +- [[raw/official-docs/hibernate-slow-query-log-official]] +- [[raw/official-docs/datasource-proxy-slow-query-official]] +- 이 자료를 인용한 wiki 요약: (미생성) diff --git a/vault/20-evidence/official-docs/privacy-cryptographic-erasure-nist-sp800-88.md b/vault/20-evidence/official-docs/privacy-cryptographic-erasure-nist-sp800-88.md new file mode 100644 index 0000000..0963c56 --- /dev/null +++ b/vault/20-evidence/official-docs/privacy-cryptographic-erasure-nist-sp800-88.md @@ -0,0 +1,99 @@ +--- +title: NIST SP 800-88 Rev.1 — Cryptographic erasure +source_type: official-doc +status: raw +confidence: high +url: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-88r1.pdf +archive_url: +tags: [privacy, cryptographic-erasure, data-deletion, nist, gdpr, ca-skeleton] +related_branches: [feature-data-retention-privacy-contract] +related_projects: [ca-skeleton-operational-contract] +created: 2026-05-22 +last_reviewed: 2026-05-27 +--- + +# NIST SP 800-88 Rev.1 — Guidelines for Media Sanitization (Cryptographic Erase) + +> Layer: `raw/official-docs/` — NIST SP 800-88 Rev.1 § 2.5 Cryptographic Erase (CE) 정식 정의. ca-tmpl backup 의 PII 단건 erasure 결정 (row delete vs key destruction) 의 1차 근거. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-data-retention-privacy-contract]] | ca-tmpl backup retention (30d daily + 6m monthly) 안에서 DSR delete SLA 30일이 "DB row 삭제" 가 아닌 "encryption key 삭제 (CE)" 로 충족될 수 있다는 근거 | +| [[raw/project-notes/ca-skeleton-operational-contract]] | ca-tmpl Group G-J (Privacy / File / Domain Modeling) 의 cryptographic erase 선행 입력 자료 | + +## 컨텍스트 + +ca-tmpl 의 DSR delete SLA 30일이 "DB row 삭제" 를 의미하는지 "encryption key 삭제" 로 충분한지가 미정. NIST SP 800-88 은 **Cryptographic Erase(CE)** 를 정식 sanitization technique 으로 인정. ca-tmpl backup retention (30일 daily + 6개월 monthly) 에서 backup 안의 PII 를 어떻게 "삭제" 할지 결정할 때 직접 영향. + +## 출처 / Source + +- 원본 URL: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-88r1.pdf +- 아카이브 URL: (미수집) +- 저자/조직: NIST (US National Institute of Standards and Technology), Richard Kissel et al. +- 발행일: 2014-12 (Rev.1) +- 마지막 확인일: 2026-05-27 +- 보조: ENISA "Cryptographic erasure" briefing, AWS KMS docs ("Deleting customer master keys") +- 참고: 2025-09-26 부로 본 Rev.1 은 withdrawn 되고 Rev.2 로 superseded. 본 raw 의 quote/Claim 은 Rev.1 § 2.5 기준이며, 후속 작업에서 Rev.2 텍스트 대조 필요. + +## 핵심 인용 / Key quotes (verbatim) + +> [§2.5] "Cryptographic Erase (CE) leverages the encryption of target data by enabling sanitization of the target data's encryption key. This leaves only the ciphertext remaining on the media, effectively sanitizing the data by preventing read-access." + +> [§2.5] "For CE to be effective, the cryptographic algorithm and all of its parameters (e.g., key length, mode) must be at security strength of 112 bits or higher (e.g., AES-128 or higher)." + +> [§2.5] "After CE is used to sanitize media, the encrypted data remaining on the media cannot be feasibly recovered or read because the encryption key has been sanitized." + +> [§2.5] "Verification of CE is typically performed by validating that the key destruction occurred per the manufacturer or vendor's specifications." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| NIST-CE-C1 | Cryptographic Erase (CE) 는 target data 의 **encryption key 를 sanitize 하여** target data 자체의 sanitization 효과를 내는 기법 — ciphertext 는 media 에 잔존하나 read-access 가 차단됨 | [§2.5] "Cryptographic Erase (CE) leverages the encryption of target data by enabling sanitization of the target data's encryption key. This leaves only the ciphertext remaining on the media, effectively sanitizing the data by preventing read-access." | `official-standard` | NIST 가 인정하는 media sanitization 의 대안 기법 (clear/purge/destroy 외) | CE 가 모든 매체/모든 시나리오에서 충분하다는 뜻은 아님 — NIST 문서는 데이터 분류 + threat model 별로 clear/purge/destroy 매칭 표 제공 | +| NIST-CE-C2 | CE 가 effective 하려면 cryptographic algorithm 과 모든 parameter (key length, mode) 가 **security strength 112-bit 이상** (예: AES-128 이상) 이어야 한다 | [§2.5] "For CE to be effective, the cryptographic algorithm and all of its parameters (e.g., key length, mode) must be at security strength of 112 bits or higher (e.g., AES-128 or higher)." | `official-standard` | CE 를 sanitization technique 으로 주장하려는 모든 시스템 | 더 강한 알고리즘 요구 (AES-256, ChaCha20 등) 라는 뜻은 아님 — 112-bit 는 **최소 요건** | +| NIST-CE-C3 | CE 후 media 에 남은 encrypted data 는 encryption key 가 sanitize 되었기 때문에 **feasibly 복구·읽기 불가** | [§2.5] "After CE is used to sanitize media, the encrypted data remaining on the media cannot be feasibly recovered or read because the encryption key has been sanitized." | `official-standard` | key destruction 이 정확히 수행된 경우의 사후 상태 | key 가 단순 marking 만 되고 실제 destroy 되지 않은 경우 (KMS 의 일부 soft-delete 모드 등) 는 본 보증 밖. key escrow / replicated key 존재 시도 무효 | +| NIST-CE-C4 | CE 의 verification 은 manufacturer / vendor 의 specification 에 따라 **key destruction 이 실제로 발생했음을 validate** 하는 방식으로 수행됨 | [§2.5] "Verification of CE is typically performed by validating that the key destruction occurred per the manufacturer or vendor's specifications." | `official-standard` | CE 를 운영 절차로 채택한 모든 환경 | "validate 방법" 의 통일된 표준 절차가 NIST 에 직접 명시되어 있다는 뜻은 아님 — vendor specification 위임 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `NIST-CE-C1`: CE 의 정식 정의 (ciphertext 잔존 허용 + read-access 차단) + - `NIST-CE-C2`: CE 의 최소 cryptographic strength 요건 (112-bit / AES-128 이상) + - `NIST-CE-C3`: CE 후 데이터 복구 불가성 (cryptographic 보증) + - `NIST-CE-C4`: CE verification 의 일반 절차 (vendor spec validation) +- **이 자료가 증명하지 않는 것**: + - "CE 는 GDPR Art.17 의 erasure 요건을 자동으로 충족" — EU regulator 의 공식 확인은 본 NIST 표준 범위 밖 + - per-principal 또는 per-tenant envelope key 가 권장 패턴 — 본 표준은 key destruction 자체의 효과만 정의 + - cloud KMS (AWS KMS / GCP KMS) 의 `ScheduleKeyDeletion` 등 구체적 API 가 CE verification 요건을 충족 — vendor 별 별도 검증 필요 + - quantum-resistant 미래 시점에서도 ciphertext 가 영구적으로 read-impossible — 현재 cryptographic strength 하에서의 보증 +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 의 DSR delete 옵션 A (row delete) vs 옵션 B (CE) 중 채택안 + - per-principal envelope key vs per-tenant key 의 cost/운영 trade-off (별도 raw `gdpr-cryptographic-erasure-envelope-key-pattern` 참조) + - NIST SP 800-88 Rev.2 (2025-09-26 supersession) 의 CE 관련 변경 사항 검토 + - KMS vendor 가 제공하는 "key destruction validation" 메커니즘이 NIST `NIST-CE-C4` 요건 (vendor spec validation) 을 충족하는지 + +## 메모 + +- ca-tmpl 적용 (자료 직접 인용 아님): + - **DSR delete 옵션 A (row delete):** DB row 자체 삭제. backup 에 남는 row 는 retention 만료 시까지 잔존 → GDPR Art. 17 "right to erasure" 위배 가능. + - **DSR delete 옵션 B (cryptographic erase):** principal 별 envelope key 를 KMS 에서 destroy. backup 에 ciphertext 는 남지만 복호화 불가 → NIST SP 800-88 이 정식으로 인정하는 sanitization. + - ca-tmpl 의 "tombstone/pseudonymization allowed" 결정은 cryptographic erase 와 호환되나 **per-principal key** 구조가 전제되어야 함. +- 트레이드오프: + - cryptographic erase 는 backup-friendly (rewriting backups 불필요) 하지만 key management 복잡도 증가 (per-principal key, key rotation, KMS cost). + - row delete 는 simple 하지만 backup retention 기간 동안 GDPR 노출. +- ca-tmpl 미결정: per-principal envelope key vs per-tenant key. 본 raw 는 후속 결정 input. + +## Related / 관련 + +- 같은 주제 다른 official-doc: + - [[raw/official-docs/gdpr-cryptographic-erasure-envelope-key-pattern]] — per-principal envelope key 후보 (a/b/c) 합성 + - [[raw/official-docs/privacy-gdpr-article-25-design]] — GDPR Art.25 (privacy by design) +- 인용하는 branch: + - [[raw/branch-notes/feature-data-retention-privacy-contract]] +- canonical contract 섹션: + - [[raw/project-notes/ca-skeleton-operational-contract]] (#18. Control Plane Contract) +- 대안 그룹: **Group G-J — Privacy / File / Domain Modeling** (data retention / privacy) +- 본 source 의 위치: 대안 1 — NIST SP 800-88 Cryptographic Erase (backup 의 PII delete: row delete vs key destruction) +- 인용하는 wiki: (미작성) diff --git a/vault/20-evidence/official-docs/privacy-gdpr-article-25-design.md b/vault/20-evidence/official-docs/privacy-gdpr-article-25-design.md new file mode 100644 index 0000000..09c448f --- /dev/null +++ b/vault/20-evidence/official-docs/privacy-gdpr-article-25-design.md @@ -0,0 +1,103 @@ +--- +title: GDPR Article 25 — Data protection by design and by default +source_type: official-doc +status: raw +confidence: high +url: https://gdpr-info.eu/art-25-gdpr/ +archive_url: https://web.archive.org/web/2024/https://gdpr-info.eu/art-25-gdpr/ +tags: [privacy, gdpr, data-retention, privacy-by-design, ca-skeleton] +related_branches: [feature-data-retention-privacy-contract] +related_projects: [ca-skeleton-operational-contract] +created: 2026-05-22 +last_reviewed: 2026-05-27 +--- + +# GDPR Article 25 — Data protection by design and by default + +> Layer: `raw/official-docs/` — Regulation (EU) 2016/679 Article 25 (privacy by design + by default) 의 verbatim 발췌. ca-tmpl retention/redaction/pseudonymization 결정의 legal basis 1차 근거. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-data-retention-privacy-contract]] | ca-tmpl 의 application log 30d / security 180d / audit 365d retention 과 HMAC-SHA-256 + 90d salt rotation pseudonymization 의 legal basis (Art. 25(1) pseudonymisation + Art. 25(2) storage limitation) | +| [[raw/project-notes/ca-skeleton-operational-contract]] | ca-tmpl baseline 의 "GDPR aligned" 외부 산출물 표현 근거 | + +## 컨텍스트 + +ca-tmpl 의 retention/redaction/pseudonymization 결정(`feature-data-retention-privacy-contract`) 이 단순히 "30/180/365일" 이라는 수치 뿐 아니라 **legal basis** 가 있어야 외부 산출물에서 "GDPR aligned" 라고 말할 수 있음. Article 25 는 storage limitation, data minimization, pseudonymization 을 default 로 요구하는 핵심 조항. + +## 출처 / Source + +- 원본 URL: https://gdpr-info.eu/art-25-gdpr/ +- 아카이브 URL: https://web.archive.org/web/2024/https://gdpr-info.eu/art-25-gdpr/ +- 보조: EDPB Guidelines 4/2019 on Article 25 — https://edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-42019-article-25-data-protection-design-and_en +- 저자/조직: European Union (Regulation 2016/679) +- 발행일: 2016-04-27 발효 2018-05-25 +- 마지막 확인일: 2026-05-27 + +## 핵심 인용 / Key quotes (verbatim) + +### Article 25(1) — Data protection by design + +> [§Art. 25(1)] "Taking into account the state of the art, the cost of implementation and the nature, scope, context and purposes of processing as well as the risks of varying likelihood and severity for rights and freedoms of natural persons posed by the processing, the controller shall, both at the time of the determination of the means for processing and at the time of the processing itself, implement appropriate technical and organisational measures, such as pseudonymisation, which are designed to implement data-protection principles, such as data minimisation, in an effective manner and to integrate the necessary safeguards into the processing in order to meet the requirements of this Regulation and protect the rights of data subjects." + +### Article 25(2) — Data protection by default + +> [§Art. 25(2)] "The controller shall implement appropriate technical and organisational measures for ensuring that, by default, only personal data which are necessary for each specific purpose of the processing are processed." + +> [§Art. 25(2)] "That obligation applies to the amount of personal data collected, the extent of their processing, the period of their storage and their accessibility." + +> [§Art. 25(2)] "In particular, such measures shall ensure that by default personal data are not made accessible without the individual's intervention to an indefinite number of natural persons." + +### EDPB Guidelines 4/2019 (보조) + +> EDPB Guidelines 4/2019: "Retention periods should be set as short as possible and reviewed regularly. Pseudonymisation, encryption and access controls are among the key safeguards." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| GDPR-A25-C1 | Art. 25(1) 는 controller 가 처리 수단 결정 시점 + 처리 자체 시점 양쪽에서 **pseudonymisation 과 같은 적절한 기술·조직 조치** 를 구현하여 data-protection 원칙(data minimisation 등)을 effective 하게 실현할 의무를 진다 — state of the art / cost / nature·scope·context·purposes / risk 를 고려한 비례성 적용 | [§Art. 25(1)] "the controller shall ... implement appropriate technical and organisational measures, such as pseudonymisation, which are designed to implement data-protection principles, such as data minimisation, in an effective manner" | `official-standard` | EU controllers / EU residents 의 personal data 를 처리하는 모든 시스템 | "pseudonymisation 이 항상 필수" 의 뜻은 아님 — "such as pseudonymisation" 은 예시. 비례성/risk 평가에 따라 다른 조치 가능 | +| GDPR-A25-C2 | Art. 25(2) 는 controller 가 **by default** 로 각 처리 목적에 **필요한 personal data 만** 처리되도록 보장하는 기술·조직 조치를 구현해야 한다 | [§Art. 25(2)] "the controller shall implement appropriate technical and organisational measures for ensuring that, by default, only personal data which are necessary for each specific purpose of the processing are processed." | `official-standard` | 모든 EU 적용 controller | 특정 retention 일수 / 저장 기간 / pseudonymization 알고리즘이 강제된다는 뜻은 아님 — "necessary for purpose" 의 정량 기준은 도메인별 | +| GDPR-A25-C3 | Art. 25(2) 의 default 의무는 **(i) 수집되는 personal data 의 양, (ii) 처리 범위, (iii) 저장 기간, (iv) 접근성** 4가지 모두에 적용된다 | [§Art. 25(2)] "That obligation applies to the amount of personal data collected, the extent of their processing, the period of their storage and their accessibility." | `official-standard` | 시스템 설계 시 4축 모두 고려 의무 | 4가지 외의 차원 (예: 위치, 처리 빈도) 은 본 조항이 직접 다루지 않음 — 다른 GDPR 조항으로 보강 | +| GDPR-A25-C4 | Art. 25(2) 는 특히 personal data 가 **개인의 개입 없이 (without the individual's intervention)** 무제한의 자연인에게 접근 가능하도록 만들어서는 안 된다고 명시 — 예: 기본 공개 설정 금지 | [§Art. 25(2)] "In particular, such measures shall ensure that by default personal data are not made accessible without the individual's intervention to an indefinite number of natural persons." | `official-standard` | social/sharing 기능 / 기본 공개 설정 의 default 정책 | 공개 설정 자체가 금지된다는 뜻은 아님 — "by default" + "without individual's intervention" 조합이 핵심 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `GDPR-A25-C1`: pseudonymisation 이 Art. 25(1) 의 명시적 예시로 등장. ca-tmpl 의 HMAC-SHA-256 + 90d salt rotation 이 "appropriate technical measure" 후보임 + - `GDPR-A25-C2`: data minimisation 의 default 의무 + - `GDPR-A25-C3`: 저장 기간 (retention) 이 default 의무의 4축 중 하나로 명시 — ca-tmpl 30/180/365d 의 legal basis + - `GDPR-A25-C4`: 기본 공개 설정 금지 원칙 +- **이 자료가 증명하지 않는 것**: + - 30/180/365일 retention 이 GDPR 이 요구하는 정확한 수치 — Art. 25 는 수치를 지정하지 않음. "as short as possible" 원칙만 (EDPB 가이드 보조) + - HMAC-SHA-256 + 90d salt rotation 이 pseudonymisation 의 충분조건 — 알고리즘 강도/key management 는 ENISA / IAPP 가이드 보강 필요 + - ca-tmpl 의 DSR delete SLA 30일이 Art. 25 의 직접 요구 — 별도 Art. 12(3) "without undue delay and in any event within one month" 와 결합 해석 필요 + - 4축 (수집량/처리범위/저장기간/접근성) 외 차원에 대한 default 의무 +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 의 "necessary for purpose" justification 을 도메인별 (application / security / audit log) 로 명문화 + - is_sample column 이 data minimization 원칙과 호환됨을 운영 정책 문서로 명문화 + - 90d salt rotation 이 EDPB 가 권장하는 "periodic re-pseudonymisation" 의 적정 주기인지 별도 검토 + +## 메모 + +- ca-tmpl 과의 매핑 (자료 직접 인용 아님): + - `application log 30일 / security 180일 / audit 365일` retention 은 Art. 25(2) "period of their storage" 원칙과 호환. 단, "necessary for each specific purpose" justification 이 도메인별로 따로 필요. + - HMAC-SHA-256 salt rotation 90d 는 Art. 25(1) "pseudonymisation" 의 기술적 조치에 해당. salt rotation 이 없으면 pseudonymization 이 사실상 정적 hash 가 되어 re-identification risk 증가. + - is_sample column 은 data minimization 원칙과 충돌하지 않음 (prod 에서 sample 이 절대 seed 되지 않음을 보장). +- 한계: Article 25 자체는 retention 수치를 지정하지 않음. "as short as possible" 원칙만. 30/180/365일은 ca-tmpl 의 **운영적 기본값** 일 뿐 법적 강제값 아님. +- ca-tmpl 의 DSR SLA(delete 30d / export 14d) 는 Article 12(3) "without undue delay and in any event within one month" 와 호환. + +## Related / 관련 + +- 같은 주제 다른 official-doc: + - [[raw/official-docs/privacy-cryptographic-erasure-nist-sp800-88]] — CE 정식 정의 + - [[raw/official-docs/gdpr-cryptographic-erasure-envelope-key-pattern]] — Art.17 backup erasure 보강 패턴 +- 인용하는 branch: + - [[raw/branch-notes/feature-data-retention-privacy-contract]] +- canonical contract 섹션: + - [[raw/project-notes/ca-skeleton-operational-contract]] (#18. Control Plane Contract) +- 대안 그룹: **Group G-J — Privacy / File / Domain Modeling** (data retention / privacy) +- 본 source 의 위치: **ca-tmpl baseline 근거** — GDPR Art.25 (Privacy by design/default). 30/180/365d retention 의 legal basis +- 인용하는 wiki: (미작성) diff --git a/vault/20-evidence/official-docs/problem-detail-rfc-7807.md b/vault/20-evidence/official-docs/problem-detail-rfc-7807.md new file mode 100644 index 0000000..3134f6a --- /dev/null +++ b/vault/20-evidence/official-docs/problem-detail-rfc-7807.md @@ -0,0 +1,129 @@ +--- +title: RFC 7807 Problem Details for HTTP APIs +source_type: official-doc +url: https://datatracker.ietf.org/doc/html/rfc7807 +archive_url: +status: reviewed +confidence: high +tags: [ca-error-envelope, rfc7807, problem-detail, rest-api, http] +related_projects: [ca-skeleton-operational-contract] +related_branches: [feature-operational-error-observability-foundation, feature-boundary-validation-mapping-contract, feature-business-rule-validation-contract] +created: 2026-05-22 +last_reviewed: 2026-05-27 +--- + +# RFC 7807 — Problem Details for HTTP APIs + +> Layer: `raw/official-docs/` — IETF RFC 7807 의 HTTP API error envelope 표준. ca-tmpl 이 명시적으로 forbidden 으로 둔 표준 — 채택 안한 결정의 trade-off 평가 근거. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-operational-error-observability-foundation]] | ca-tmpl custom envelope vs RFC 7807 ProblemDetail 채택 결정의 표준 reference | +| [[raw/branch-notes/feature-boundary-validation-mapping-contract]] | boundary validation error 시 응답 shape 결정 (RFC 7807 미채택 근거) | +| [[raw/branch-notes/feature-business-rule-validation-contract]] | business rule violation 응답 shape 결정 (RFC 7807 미채택 근거) | +| [[raw/project-notes/ca-skeleton-operational-contract]] | §3. Structured API Response Contract + §6. Operational Error Category — 미채택 표준 reference | + +## 컨텍스트 / 왜 저장했는지 + +ca-tmpl 이 명시적으로 **forbidden** 으로 둔 표준. custom envelope (`{success, data, error.{code,category,message,retryable,details}, meta}`) 결정의 trade-off 를 평가하려면 표준의 정확한 shape, 확장 메커니즘, 한계를 먼저 알아야 함. RFC 7807 은 현재 RFC 9457 로 obsolete 되었으나 본 문서는 7807 기준 정리. + +## 출처 / Source + +- 원본 URL: https://datatracker.ietf.org/doc/html/rfc7807 +- 후속 RFC (obsolete 시킴): RFC 9457 (Problem Details for HTTP APIs — 2023 revision) +- Media type: `application/problem+json`, `application/problem+xml` +- 아카이브 URL: (미수집) +- 저자 / 조직: IETF (Editors: M. Nottingham, E. Wilde) +- 발행일: RFC 7807 — March 2016 +- 마지막 확인일: 2026-05-27 (WebFetch 재검증 성공 — 5개 quote 모두 verbatim 일치. strength `needs-confirmation` → `official-standard` 으로 upgrade. [2026-05-25 capture] verbatim 보존본 유지) + +## 핵심 인용 / Key quotes (verbatim) + +> [§3.1, captured 2026-05-22] "The canonical model for problem details is a JSON object. When serialized as a JSON document, that format is identified with the 'application/problem+json' media type." + +> [§3.1, captured 2026-05-22] "Consumers MUST use the 'type' string as the primary identifier for the problem type; the 'title' string is advisory and included only for users who are not aware of the semantics of the URI." + +> [§3.2 — Extension Members, captured 2026-05-22] "Problem type definitions MAY extend the problem details object with additional members... Clients consuming problem details MUST ignore any such extensions that they don't recognize." + +> [§3.1 — status, captured 2026-05-22] "Generators MUST use the same status code in the actual HTTP response, to assure that generic HTTP software that does not understand this format still behaves correctly." + +> [§3.1 — detail, captured 2026-05-22] "The 'detail' member, if present, ought to focus on helping the client correct the problem, rather than giving debugging information." + +> **[2026-05-27 verified — WebFetch 재검증 성공]**: 본 5개 quote (RFC7807-C1 ~ C5) 모두 https://datatracker.ietf.org/doc/html/rfc7807 live 페이지에서 FOUND VERBATIM. §번호 확인: C1 = §3, C2/C4/C5 = §3.1, C3 = §3.2. strength `needs-confirmation` → `official-standard` (IETF RFC) 으로 upgrade. [2026-05-25 capture] verbatim 본문 유지. RFC 9457 (후속) 과의 차이는 별도 raw 작성 시 검증. + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| RFC7807-C1 | problem details 의 canonical model 은 JSON object 이며, `application/problem+json` media type 으로 식별 | [§3, captured 2026-05-22 + 2026-05-27 verified verbatim] "The canonical model for problem details is a JSON object. When serialized as a JSON document, that format is identified with the 'application/problem+json' media type." | `official-standard` [2026-05-27 verified, IETF RFC] | HTTP API 의 error 응답 shape | XML 응답 (`application/problem+xml`) 도 동등하게 정의되어 있으나 본 인용 범위 밖 | +| RFC7807-C2 | consumer 는 `type` string 을 problem type 의 primary identifier 로 사용해야 하며 (`MUST`), `title` 은 advisory | [§3.1, captured 2026-05-22 + 2026-05-27 verified verbatim] "Consumers MUST use the 'type' string as the primary identifier for the problem type; the 'title' string is advisory and included only for users who are not aware of the semantics of the URI." | `official-standard` [2026-05-27 verified, IETF RFC] | RFC 7807 consumer 구현 | `code` 같은 짧은 머신리더블 식별자가 표준에 1급 필드로 있다는 뜻은 아님 — `type` URI 가 식별자 역할 | +| RFC7807-C3 | problem type 정의는 추가 member 로 확장 가능 (`MAY`), client 는 알 수 없는 확장을 무시해야 함 (`MUST`) | [§3.2 — Extension Members, captured 2026-05-22 + 2026-05-27 verified verbatim] "Problem type definitions MAY extend the problem details object with additional members... Clients consuming problem details MUST ignore any such extensions that they don't recognize." | `official-standard` [2026-05-27 verified, IETF RFC] | RFC 7807 의 확장 메커니즘 (예: `balance`, `retryable` 등) | 어떤 확장 필드를 표준이 권장한다는 뜻은 아님 — `code`/`category`/`retryable` 모두 확장 영역 | +| RFC7807-C4 | generator 는 problem details body 의 `status` 필드와 실제 HTTP response 의 status code 를 동일하게 사용해야 함 (`MUST`) | [§3.1 — status, captured 2026-05-22 + 2026-05-27 verified verbatim] "Generators MUST use the same status code in the actual HTTP response, to assure that generic HTTP software that does not understand this format still behaves correctly." | `official-standard` [2026-05-27 verified, IETF RFC] | RFC 7807 generator 구현 | HTTP status code 의 정확한 mapping (404 vs 422 등) 은 별도 표준. 본 인용은 일치 요구만 | +| RFC7807-C5 | `detail` member 는 client 가 문제를 정정하는 데 도움을 주는 데 초점을 두어야 하며, debugging 정보 제공이 아닌 (`ought to`) | [§3.1 — detail, captured 2026-05-22 + 2026-05-27 verified verbatim] "The 'detail' member, if present, ought to focus on helping the client correct the problem, rather than giving debugging information." | `official-standard` [2026-05-27 verified, IETF RFC] | `detail` 필드의 의도된 용도 | i18n / localization 표준은 별도 — `detail` 의 언어 정책은 본 인용 범위 밖. `ought to` 는 `SHOULD` 보다 약한 어조 | +| RFC7807-C6 | i18n / `Accept-Language` 기반 message localization 은 RFC 7807 표준에 **명시 없음** | (부재 자체가 claim — 2026-05-27 WebFetch 재검증 시에도 i18n / Accept-Language 관련 normative 진술 발견되지 않음) | `official-standard` [2026-05-27 verified — 부재 사실 확인] | 다국어 error message 정책 | RFC 7807 이 i18n 을 금지한다는 뜻 아님 — 구현자 책임 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것** (2026-05-22 capture + 2026-05-27 WebFetch verbatim 재검증): + - `RFC7807-C1`: media type `application/problem+json` 이 정식 IANA 등록 type + - `RFC7807-C2`: `type` URI 가 primary identifier (= 짧은 `code` 필드는 표준 1급 아님) + - `RFC7807-C3`: 확장 메커니즘 + unknown extension ignore 규칙 + - `RFC7807-C4`: body status 와 HTTP status 일치 의무 + - `RFC7807-C5`: `detail` 의 의도된 용도 (디버깅 정보 아님) +- **이 자료가 증명하지 않는 것**: + - 성공 응답 shape (RFC 7807 은 실패 전용 — 성공/실패 비대칭) + - 짧은 머신리더블 `code` 필드의 표준 부재 (`RFC7807-C2` 의 함의 — 확장 필드 사용 필요) + - `category` / `retryable` / `correlation-id` 같은 운영 메타데이터 (`C3` 의 확장 영역) + - i18n / Accept-Language 정책 (`C6`) + - 외부 client 라이브러리의 실제 `application/problem+json` 지원 범위 +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - 2026-05-27 시점 재확인 + RFC 9457 (후속) 과의 차이 검토 (특히 `type` URI 의 안정성 요구사항, `instance` URI 동작) + - ca-tmpl 의 `{success, data, error.{code,category,message,retryable,details}, meta}` 균일 shape 가 `RFC7807-C2` 의 `type` URI primary identifier 와 어떻게 충돌하는지 (custom `code` 채택 trade-off) + - Spring Boot `ProblemDetail` API (Spring Framework 6+) 와 ca-tmpl custom envelope 의 호환성 + +## ca-tmpl 함의 (내 프로젝트 해석) + +> 본 섹션은 자료 직접 인용이 아닌 ca-tmpl 결정 컨텍스트 해석. wiki 추출 시 source-summary 로 옮겨야 함. + +- **표준 vs custom 의 trade-off**: + - 표준 준수도 ↑ (RFC 7807), client lock-in ↓. 단 `application/problem+json` content negotiation 처리 client 가 드뭄 → 실질 호환성은 custom 과 큰 차이 없음 (해석). + - 성공/실패 shape 비대칭 (실패 전용) vs ca-tmpl 균일 shape (`success: false` 분기) — DX 트레이드오프. + - `type` URI 카탈로그 운영 부담 vs custom `code` enum 단순성. +- **운영 메타데이터**: `category` / `retryable` / `code` 모두 RFC 7807 확장 영역 (`RFC7807-C3`). custom envelope 으로 1급 필드 승격하는 것이 ca-tmpl 결정. +- **상태 코드 정합**: ca-tmpl 도 `RFC7807-C4` 와 동일하게 HTTP status code 와 body 상태 일치 의무 (직접적 표준 인용은 아니지만 동일 원칙). + +## 응답 shape 예시 (RFC 7807) + +```json +{ + "type": "https://example.com/probs/out-of-credit", + "title": "You do not have enough credit.", + "status": 403, + "detail": "Your current balance is 30, but that costs 50.", + "instance": "/account/12345/msgs/abc" +} +``` + +- 모든 필드 optional. `type` 미지정 시 `"about:blank"`. +- 확장: top-level 에 임의 필드 추가 가능 (예: `balance`, `accounts`) — `RFC7807-C3`. + +## 메모 / Notes + +- **재검증 완료**: 2026-05-27 datatracker WebFetch 재검증 성공 (5/5 verbatim, §번호 확인 — C1=§3, C2/C4/C5=§3.1, C3=§3.2). +- **RFC 9457 후속**: 7807 은 obsolete. wiki 승급 시 9457 기준으로 업데이트할지 결정 필요. +- **단점 (해석)**: i18n 미지원, code 필드 없음 (확장 영역), 성공 응답 별도 — custom envelope 대비 운영 부담 큼. + +## Related / 관련 + +- 같은 주제 다른 raw / 표준: + - RFC 9457 (Problem Details — 2023 revision) — 별도 raw 작성 후보 + - Spring `ProblemDetail` API (Spring Framework 6+) — 별도 raw 작성 후보 +- 인용하는 branch: + - [[raw/branch-notes/feature-operational-error-observability-foundation]] + - [[raw/branch-notes/feature-boundary-validation-mapping-contract]] + - [[raw/branch-notes/feature-business-rule-validation-contract]] +- 인용하는 project: + - [[raw/project-notes/ca-skeleton-operational-contract]] (§3, §6) +- 인용한 wiki 요약: (미작성) diff --git a/vault/20-evidence/official-docs/prometheus-alertmanager-silences.md b/vault/20-evidence/official-docs/prometheus-alertmanager-silences.md new file mode 100644 index 0000000..2e72b91 --- /dev/null +++ b/vault/20-evidence/official-docs/prometheus-alertmanager-silences.md @@ -0,0 +1,101 @@ +--- +title: "Prometheus Alertmanager — Silences" +source_type: official-doc +url: https://prometheus.io/docs/alerting/latest/alertmanager/ +archive_url: +status: raw +confidence: high +tags: [observability, alerting, prometheus, alertmanager, silence, runbook, maintenance] +related_projects: [] +related_branches: [feature-operational-runbook-contract] +created: 2026-05-27 +last_reviewed: 2026-05-27 +--- + +# Prometheus Alertmanager — Silences + +> Layer: `raw/official-docs/` — Prometheus Alertmanager 공식 문서의 "Silences" 섹션 원문 발췌. ca-tmpl runbook 의 maintenance window 동안 알람 suppression 메커니즘의 근거. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-operational-runbook-contract]] | D6 maintenance window 중 알람 silence 메커니즘 채택 근거 — Alertmanager 의 silence 가 시간 제한 + matcher 기반 알람 mute 의 공식 메커니즘 | + +## 컨텍스트 + +ca-tmpl `feature-operational-runbook-contract` 의 D6 는 계획된 maintenance / deploy window 동안 false-positive 알람이 oncall 을 깨우지 않도록 silence 를 적용한다는 결정. 본 source 는 그 silence 메커니즘의 Prometheus 공식 정의 — silence 는 시간 제한 mute 이며 matcher (equality 또는 regex) 로 대상 알람을 지정. + +## 출처 / Source + +- 원본 URL: https://prometheus.io/docs/alerting/latest/alertmanager/ +- 직접 anchor: https://prometheus.io/docs/alerting/latest/alertmanager/#silences +- 아카이브 URL: (미수집) +- 저자 / 조직: Prometheus Authors (CNCF) +- 발행일: rolling docs +- 마지막 확인일: 2026-05-27 + +## 왜 저장했는지 / Why archived + +maintenance window 알람 처리를 "Alertmanager silence 를 쓴다" 라고 결정할 때, silence 가 (a) 시간 제한 mute 이며 (b) matcher 기반으로 대상 알람을 지정한다는 두 핵심 속성을 공식 verbatim 으로 보존. ca-tmpl runbook 의 "maintenance window 시작 시 silence 생성, 종료 시 자동 만료" 흐름의 근거. + +## 핵심 인용 / Key quotes (verbatim) + +> [§Silences] "Silences are a straightforward way to simply mute alerts for a given time." + +> [§Silences] "A silence is configured based on matchers, just like the routing tree." + +> [§Silences] "Incoming alerts are checked whether they match all the equality or regular expression matchers of an active silence." + +> [§Silences] "If they do, no notifications will be sent out for that alert." + +> [§Silences] "Silences are configured in the web interface of the Alertmanager." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| ALERTMANAGER-SIL-C1 | silence 는 주어진 시간 동안 알람을 mute 하는 메커니즘 (= 시간 제한 suppression) | [§Silences] "Silences are a straightforward way to simply mute alerts for a given time." | `official-vendor-doc` | Alertmanager 가 처리하는 모든 알람 | "given time" 의 정확한 grammar (start / end / duration / 무기한 silence 가능 여부) 는 본 인용 범위 밖 — UI / API spec 별도 | +| ALERTMANAGER-SIL-C2 | silence 는 routing tree 와 동일한 방식으로 matcher 기반으로 설정 | [§Silences] "A silence is configured based on matchers, just like the routing tree." | `official-vendor-doc` | silence 와 routing 모두 | routing tree 의 정확한 spec 은 별도 (alertmanager config `route:`) | +| ALERTMANAGER-SIL-C3 | incoming alert 가 active silence 의 equality 또는 regex matcher 를 **모두 (all)** 만족하면 silence 적용 | [§Silences] "Incoming alerts are checked whether they match all the equality or regular expression matchers of an active silence." | `official-vendor-doc` | silence 의 매칭 조건 평가 | matcher 가 부분 일치 / 음의 매칭 (negation) 을 어떻게 표현하는지는 별도 spec (matcher syntax) | +| ALERTMANAGER-SIL-C4 | silence 가 매칭된 알람은 notification 이 전송되지 않음 | [§Silences] "If they do, no notifications will be sent out for that alert." | `official-vendor-doc` | silence 매칭된 모든 알람 | silence 가 알람 자체의 firing 상태를 변경하지 **않음** (= 알람은 여전히 발화 중이고 notification 만 억제) 은 본 인용 범위 밖 (관습적 해석) | +| ALERTMANAGER-SIL-C5 | silence 는 Alertmanager 의 web interface 에서 설정 | [§Silences] "Silences are configured in the web interface of the Alertmanager." | `official-vendor-doc` | UI 기반 silence 관리 | API / amtool CLI 를 통한 설정 가능 여부는 본 인용 범위 밖 (실제로는 가능하나, 본 verbatim 에는 web interface 만 명시) | + +### Strength + +모두 `official-vendor-doc` (Prometheus Authors / Alertmanager docs). + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `ALERTMANAGER-SIL-C1`: silence 의 시간 제한 mute 정의 + - `ALERTMANAGER-SIL-C2` ~ `C3`: matcher 기반 대상 지정 + AND (all) 조건 + - `ALERTMANAGER-SIL-C4`: notification 전송 차단 + - `ALERTMANAGER-SIL-C5`: web interface 가 설정 channel 의 하나 +- **이 자료가 증명하지 않는 것**: + - silence 의 정확한 start/end time 모델 — "given time" 만 명시되어 만료 / 무한 silence 가능 여부 verbatim 부재 + - silence 생성 시 author / comment 필수 여부 + - silence 의 만료된 후 history 보관 정책 + - amtool / Alertmanager API 를 통한 silence 자동화 — 본 인용은 web interface 만 명시 + - silence 가 알람 자체의 firing 상태를 바꾸지 않음 (= notification 만 억제) — 관습이지만 본 verbatim 에는 없음 +- **내 프로젝트 (ca-tmpl) 에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl runbook 의 maintenance window 자동화에서 silence 를 amtool CLI 로 생성할지, 또는 web UI 수동 생성할지 — amtool spec 별도 확인 + - silence 의 matcher 로 ca-tmpl 의 alert label (예: `service="ca-tmpl"`, `severity="warning"`) 이 정확히 매칭되는지 검증 + - silence 만료 후 알람이 자동 재발화되는지 (deploy 종료 후 정상화 검증) + +## 메모 / Notes + +- 본 capture 는 silence 의 **개념 정의** 만 보존 — silence 의 detailed UI / API / amtool spec 은 별도 fetch 필요 (Alertmanager API reference 또는 amtool CLI docs). +- 다음 후보 fetch: + - Alertmanager amtool docs (silence create/expire CLI) + - Alertmanager API reference (POST /api/v2/silences) + - matcher syntax spec (equality / regex / negation) + +## Related / 관련 + +- 같은 주제 다른 official-doc / company-tech-blog: (없음 — alerting 도메인의 sister capture 미수집) +- 인용하는 branch: + - [[raw/branch-notes/feature-operational-runbook-contract]] +- 인용하는 project: + - [[raw/project-notes/ca-skeleton-operational-contract]] +- 인용한 wiki 요약: (미작성) diff --git a/vault/20-evidence/official-docs/protobuf-reserved-vs-json-openapi-extension.md b/vault/20-evidence/official-docs/protobuf-reserved-vs-json-openapi-extension.md new file mode 100644 index 0000000..527a81a --- /dev/null +++ b/vault/20-evidence/official-docs/protobuf-reserved-vs-json-openapi-extension.md @@ -0,0 +1,145 @@ +--- +title: Protobuf reserved Semantics vs JSON/OpenAPI Equivalents +source_type: official-doc +url: https://protobuf.dev/programming-guides/proto3/#reserved +archive_url: +status: needs-confirmation +confidence: medium +tags: [ca-tmpl, ca-schema, protobuf, openapi, json-schema, reserved-fields] +related_projects: [ca-tmpl] +related_branches: [feature-schema-serialization-contract, feature-api-compatibility-deprecation-contract] +created: 2026-05-22 +last_reviewed: 2026-05-27 +--- + +# Protobuf reserved Semantics vs JSON/OpenAPI Equivalents + +> Layer: `raw/official-docs/` — Protobuf `reserved` 키워드 verbatim + OpenAPI 3.1 / JSON Schema 의 등가 시맨틱 부재 비교. ca-tmpl (JSON 기반) 이 schema 호환성을 강제하려면 무엇을 자체적으로 정의해야 하는지 평가하기 위한 보강 자료. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-schema-serialization-contract]] | G-F follow-up — JSON 환경에서 Protobuf `reserved` 시맨틱 흉내 메커니즘 (OpenAPI `x-` extension vs 별도 markdown catalog vs JSON Schema `deprecated`) 비교 근거 | +| [[raw/branch-notes/feature-api-compatibility-deprecation-contract]] | "removed field name 재사용 차단" 정책의 표준 도구 부재 사실 — 자체 lint / code review 강제 결정의 1차 근거 | + +## 컨텍스트 / 왜 저장했는지 + +Protobuf 의 `reserved` 키워드는 schema 호환성의 핵심 장치 — field number / name 재사용을 **컴파일러 단계에서 영구 차단**한다. ca-tmpl 은 JSON over HTTP 기반이라 `reserved` 를 직접 흉내낼 수 없고, OpenAPI / JSON Schema 에는 등가 시맨틱이 부재. G-F ([[raw/branch-notes/feature-schema-serialization-contract]]) 외부 근거 조사에서 "Protobuf `reserved` 가 JSON 환경에서 ca-tmpl 이 가장 크게 보강할 부분" 으로 식별됐으나, **어떤 메커니즘으로** 보강할지 (OpenAPI `x-` extension / 자체 markdown catalog / lint tool) 는 미정. 본 raw 는 후속 결정을 위한 시맨틱 비교 근거. + +## 출처 / Source + +- 원본 URL: https://protobuf.dev/programming-guides/proto3/#reserved +- 보조 URL: + - https://spec.openapis.org/oas/v3.1.0 (OpenAPI 3.1 spec — `deprecated` 키워드와 Specification Extensions) + - https://json-schema.org/draft/2020-12/json-schema-validation (JSON Schema `deprecated` keyword) + - https://docs.stripe.com/upgrades (Stripe API: removed field 처리) + - https://docs.github.com/en/rest/overview/api-versions (GitHub REST: removed field 처리) +- 아카이브 URL: (미수집) +- 저자 / 조직: Google / Protocol Buffers project; OpenAPI Initiative (Linux Foundation); JSON Schema org +- 발행일: continuously updated +- 마지막 확인일: 2026-05-27 + +## 핵심 인용 / Key quotes (verbatim) + +### Protobuf 공식 (proto3 guide §Reserved) + +> [§Reserved] "If you update a message type by entirely deleting a field, or commenting it out, future developers can reuse the field number when making their own updates to the type." + +> [§Reserved] "you **must** reserve the deleted field number. If you do not reserve the field number, it is possible for a developer to reuse that number in the future." + +> [§Reserved — Risks of reuse] "Reusing a field number makes decoding wire-format messages ambiguous." Identified risks include "Developer time lost to debugging", "A parse/merge error (best case scenario)", "Leaked PII/SPII", "Data corruption". + +> [§Reserved — name reuse] "Reusing an old field name later is generally safe, except when using TextProto or JSON encodings where the field name is serialized." + +### OpenAPI 3.1 / JSON Schema (보조 인용 — 보조 URL 출처) + +> [OpenAPI 3.1 §4.9 Specification Extensions, 보조 인용] "Specification Extensions... allow vendor specific extensions. The extensions properties are implemented as patterned fields that are always prefixed by `x-`." + +> [JSON Schema 2020-12 §9.3, 보조 인용] "The `deprecated` keyword applies to Schema Objects to indicate that this schema has been deprecated... but does not affect the validation of an instance." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| PRVJ-C1 | message type 에서 field 를 삭제/주석화하면 미래 개발자가 그 field number 를 재사용할 수 있다 (자동 차단 없음) | [§Reserved] "If you update a message type by entirely deleting a field, or commenting it out, future developers can reuse the field number when making their own updates to the type." | `official-standard` | proto3 컴파일러 동작 | 다른 schema 시스템 (Avro / JSON Schema) 에서 동일 위험이 있다는 뜻 아님 — Protobuf 한정 사실 | +| PRVJ-C2 | 삭제된 field number 는 **반드시** reserved 처리 필요 — reserve 안 하면 미래 개발자가 재사용 가능 | [§Reserved] "you must reserve the deleted field number. If you do not reserve the field number, it is possible for a developer to reuse that number in the future." | `official-standard` | proto3 schema 변경 워크플로 | reserved 처리가 lint / pre-commit 으로 자동 추가된다는 뜻 아님 — 개발자 명시 작성 의무 | +| PRVJ-C3 | field number 재사용 시 wire-format 디코딩이 ambiguous — 결과로 (a) 디버깅 시간 손실, (b) parse/merge error (best case), (c) PII/SPII 누출, (d) 데이터 손상 가능 | [§Reserved — Risks] "Reusing a field number makes decoding wire-format messages ambiguous." + risk list | `official-standard` | Protobuf wire-format 호환성 | 위 4가지 위험이 항상 모두 발생한다는 뜻 아님 — 시나리오별 | +| PRVJ-C4 | field name 재사용은 일반적으로 안전하나 **TextProto / JSON encoding 사용 시 위험** — 해당 인코딩에서 field name 이 직렬화되기 때문 | [§Reserved] "Reusing an old field name later is generally safe, except when using TextProto or JSON encodings where the field name is serialized." | `official-standard` | proto3 + JSON / TextProto encoding | binary 환경에서 name 재사용이 완전 자유라는 뜻 아님 — 디버깅 / 로깅 / 코드 가독성 영향 별도 | +| PRVJ-C5 | OpenAPI 3.1 의 Specification Extensions 는 `x-` 접두 vendor-specific 키 허용 (어떤 정책도 정의하지 않음, 단순 확장 허가) | [OpenAPI 3.1 §4.9, 보조 인용] "Specification Extensions... allow vendor specific extensions. The extensions properties are implemented as patterned fields that are always prefixed by `x-`." | `official-standard` | OpenAPI 3.1 spec 확장 메커니즘 | `x-removed-fields` 같은 특정 확장이 표준이라는 뜻 아님 — 자체 lint 룰을 직접 작성해야 함 | +| PRVJ-C6 | JSON Schema 2020-12 의 `deprecated` 키워드는 *비권장* 신호만 제공 — instance validation 에는 영향 없음 (재사용 차단 아님) | [JSON Schema 2020-12 §9.3, 보조 인용] "The `deprecated` keyword applies to Schema Objects to indicate that this schema has been deprecated... but does not affect the validation of an instance." | `official-standard` | JSON Schema `deprecated` 의미 | `deprecated: true` 로 Protobuf `reserved` 의 재사용 차단을 흉내낼 수 있다는 뜻 아님 — 시맨틱 다름 | + +### 미확인 / 후속 확인 필요 + +- **Stripe / GitHub 의 removed field name 재사용 정책**: 공개 문서상 명시적 reserved-style 시맨틱 부재. 본 raw 에서는 claim 으로 등록하지 않음 (보조 URL 직접 verbatim 미수집). + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `PRVJ-C1` ~ `C4`: Protobuf `reserved` 의 정확한 시맨틱과 위험 (proto3 공식) + - `PRVJ-C5` ~ `C6`: OpenAPI 3.1 `x-` extension 메커니즘 존재 + JSON Schema `deprecated` 의 validation 비영향 (보조 인용) +- **이 자료가 증명하지 않는 것**: + - JSON 환경에서 Protobuf `reserved` 와 1:1 등가인 표준 메커니즘이 **존재한다** (오히려 부재 확인) + - `x-removed-fields` 같은 특정 OpenAPI 확장이 공식 권장이라는 사실 (vendor-specific extension) + - Stripe / GitHub 가 removed field name 재사용을 공식 정책으로 명시한다는 사실 (운영 정책으로 회피 추정) +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 이 채택할 lint tool (Spectral / Redocly CLI 등) 의 custom rule 작성 가능 여부 + - 별도 markdown catalog (`docs/removed-fields-catalog.md`) 와 OpenAPI diff 의 sync 자동화 방안 + - JSON Schema `deprecated` + OpenAPI `x-` extension 조합의 실무 운영 사례 (현재 부재) + +## 메모 / Notes (내 프로젝트 해석) + +> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석. + +### Protobuf `reserved` vs JSON/OpenAPI 환경 비교 + +| 측면 | Protobuf `reserved` | OpenAPI 3.1 / JSON Schema | +|---|---|---| +| 식별자 | field number (int) + field name (string) | property name (string) | +| 재사용 차단 강제 | 컴파일러가 거부 (`.proto` 빌드 실패) | **등가 없음** — `deprecated: true` 는 표시만, 재사용 차단 아님 | +| 표현 방식 | `reserved 3, 5;` / `reserved "foo", "bar";` | (없음) → `x-removed-fields` 등 자체 extension 필요 | +| 위반 시 효과 | wire format ambiguity, PII leak, parse error | 명시적 차단 없으면 typo 또는 의도적 재사용으로 의미 충돌 가능 | +| 도구 지원 | protoc 빌드 단계 | 별도 lint / OpenAPI diff 도구 필요 (표준 부재) | + +### JSON 환경에서의 흉내 대안 + +1. **OpenAPI Specification Extension (`x-removed-fields`)**: + - OpenAPI 3.1 §4.9 가 `x-` 접두 vendor extension 을 허용. schema object 에 `x-removed-fields: ["legacyAmount", "obsoleteFlag"]` 같은 배열을 두고 CI 에서 이 목록과 신규 추가 field 이름이 겹치면 빌드 실패시키는 방식. + - 장점: schema SSOT (OpenAPI) 내부에 catalog 가 있어 표류 위험 ↓. + - 단점: `x-` extension 은 vendor-specific 이라 **표준 검증 도구 부재** — 자체 lint 룰을 직접 작성해야 한다. + +2. **JSON Schema `deprecated` keyword**: + - JSON Schema 2020-12 와 OpenAPI 3.1 이 함께 정의하는 표준 키워드. `deprecated: true` 는 *지금 사용 비권장* 신호일 뿐 **재사용 차단이 아니다**. + - field 가 완전히 사라진 뒤에는 schema 에서도 사라지므로 `deprecated` 만으로는 미래 재사용 방지가 불가. + - 결론: deprecation marker 로는 적합, reserved 시맨틱 흉내로는 **부적합**. + +3. **자체 markdown / YAML catalog**: + - 별도 파일 (예: `docs/removed-fields-catalog.md`) 에 제거된 field name / 번호 / 제거 일자 / 사유를 기록하고, code review 나 CI 에서 신규 OpenAPI diff 와 cross-check. + - 장점: tool 에 종속되지 않음, 사람이 읽기 쉬움. + - 단점: schema 와 catalog 가 별도라 sync 실패 위험. 자동화하려면 결국 lint script 가 필요. + +4. **GitHub / Stripe API 의 실제 처리** (보조 — 본 자료가 단정하지 않음): + - **Stripe**: account 단위 version pin + freeze forever 정책으로 *제거* 보다는 *구버전 영구 응답* 을 택해 재사용 문제를 회피. + - **GitHub REST**: 24개월 EOL + `410 Gone` 응답. EOL 된 version 에서 제거된 field 이름의 신규 재사용 정책은 공개 문서상 명시되지 않음 (공식 reserved-style 시맨틱 부재). + - 결론: 공개 API 사례에서도 **field name 재사용 차단의 명시적 표준은 없다**. 진영별로 운영 정책으로 회피하는 형태. + +### Trade-off + +- **OpenAPI `x-` extension 채택**: schema SSOT 에 catalog 가 통합되어 표류 ↓. 단 표준 검증 도구가 없어 자체 lint 필수, 도구 채택 자체가 코드 단계 결정. +- **자체 markdown catalog**: 가독성 ↑, tool-free. 단 schema 와 별도라 sync 실패 위험, code review 에 의존. +- **JSON Schema `deprecated` 단독**: deprecation marker 로만 적합, reserved 시맨틱 흉내 **불가**. + +### 결론 + +Protobuf `reserved` 의 wire-format 수준 강제력을 JSON 환경에서 1:1 흉내내는 표준 메커니즘은 **존재하지 않는다.** ca-tmpl 이 채택할 수 있는 현실적 옵션은 (a) OpenAPI `x-removed-fields` extension + 자체 lint, (b) 별도 markdown catalog + code review/CI, 두 가지. 둘 다 도구 선택이 따라오므로 코드 단계 (Phase C2 이후) 결정 사항. + +## Related / 관련 + +- 같은 주제 다른 official-doc: + - [[raw/official-docs/schema-protobuf-vs-json-evolution]] (선행 source — Protobuf 측 원문 발췌) + - [[raw/official-docs/schema-avro-evolution-rules]] (Avro 측 동일 주제) + - [[raw/official-docs/schema-jackson-unknown-field-handling]] (Jackson 측 unknown field) +- 인용하는 branch: + - [[raw/branch-notes/feature-schema-serialization-contract]] (G-F follow-up) + - [[raw/branch-notes/feature-api-compatibility-deprecation-contract]] +- 인용하는 wiki: (미작성) diff --git a/vault/20-evidence/official-docs/proxy-pass-request-body-nginx-official.md b/vault/20-evidence/official-docs/proxy-pass-request-body-nginx-official.md new file mode 100644 index 0000000..9215437 --- /dev/null +++ b/vault/20-evidence/official-docs/proxy-pass-request-body-nginx-official.md @@ -0,0 +1,83 @@ +--- +title: nginx — proxy_pass_request_body Directive (ngx_http_proxy_module, Official Docs) +source_type: official-doc +url: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_request_body +archive_url: +related_branches: [feature-keycloak-nginx-auth-request-integration] +related_projects: [keycloak-patterns] +tags: [official-doc, keycloak-patterns, nginx, p1a-edge-forward-auth, auth_request] +created: 2026-07-17 +last_reviewed: 2026-07-17 +--- + +# nginx — proxy_pass_request_body Directive (ngx_http_proxy_module, Official Docs) + +> Layer: `raw/official-docs/` — nginx 공식 문서 `ngx_http_proxy_module` 중 `proxy_pass_request_body` directive 단일 항목 발췌. 모듈 전체 요약이 아니라 D6(`proxy_pass_request_body off` + `Content-Length ""`)의 **메커니즘 근거 1건**만 다룬다. + +## Parent / 활용 branch + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-keycloak-nginx-auth-request-integration]] | D6 — `proxy_pass_request_body` directive 의 메커니즘 근거(L1). Default 가 `on` 이므로 명시적으로 `off` 하지 않으면 원본 request body 가 proxied server 로 전달된다는 사실. | + +## 출처 / Source + +- 원본 URL: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_request_body +- 아카이브 URL: (미수집) +- 저자 / 조직: F5 / nginx +- 발행일: 모듈 최초 도입 이후 지속 업데이트 (버전 미표시 페이지) +- 마지막 확인일: 2026-07-17 + +## 왜 저장했는지 / Why archived + +`feature-keycloak-nginx-auth-request-integration` TODO 중 `/oauth2/auth` internal location 에 `proxy_pass_request_body off;` 를 두는 결정(D6)이 이전에는 `UNSUPPORTED_DECISION` 이었다. 본 자료는 directive 의 공식 Syntax/Default/Context/설명을 확정해 D6 을 L0(존재)에서 L1(메커니즘)로 끌어올리는 근거로 저장. + +## 핵심 인용 / Key quotes (verbatim) + +> [Directive: proxy_pass_request_body — Syntax] "proxy_pass_request_body on | off;" + +> [Directive: proxy_pass_request_body — Default] "proxy_pass_request_body on;" + +> [Directive: proxy_pass_request_body — Context] "http, server, location" + +> [Directive: proxy_pass_request_body — Description] "Indicates whether the original request body is passed to the proxied server." + +> [Directive: proxy_pass_request_body — Example] "location /x-accel-redirect-here/ { proxy_method GET; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_pass ... }" + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| NGXPM-C1 | `proxy_pass_request_body` 의 기본값은 `on` 이며, 이는 "원본 request body 가 proxied server 로 전달되는지 여부"를 나타낸다. 즉 `http`/`server`/`location` context 에서 명시적으로 `off` 하지 않으면 원본 body 가 그대로 전달된다. | "proxy_pass_request_body on \| off;" + "proxy_pass_request_body on;" + "http, server, location" + "Indicates whether the original request body is passed to the proxied server." | `official-vendor-doc` | `proxy_pass` directive 로 upstream 에 요청을 전달하는 `location`(또는 `http`/`server`) block 의 request body 전달 여부 결정 | subrequest 의 목적지가 반드시 `proxy_pass` 기반 location 이라는 것을 증명하지 않는다 — subrequest 가 `fastcgi_pass` 등 다른 handler 로 라우팅되면 이 directive 자체가 적용되지 않을 수 있다. 원문은 이 경우를 다루지 않는다. auth_request 서브리퀘스트가 반드시 이 directive 의 영향을 받는 location 으로 라우팅된다는 것도 증명하지 않는다. | +| NGXPM-C2 | 공식 예제는 `proxy_pass_request_body off;` 를 `proxy_set_header Content-Length "";` 와 짝지어 사용한다 (`proxy_method GET;` 도 함께 지정된 X-Accel-Redirect 스타일 `location` 블록 예제). | "location /x-accel-redirect-here/ { proxy_method GET; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_pass ... }" | `official-vendor-doc` | body 를 전달하지 않을 때(`off`) 남아있는 원본 `Content-Length` 헤더를 비워 upstream 에 잘못된 값이 전달되지 않도록 하는 조합 패턴의 존재 | 이 조합이 **auth_request 서브리퀘스트에 대해 "공식적으로 필수"임을 증명하지 않는다** — 이 예제는 X-Accel-Redirect 용 `location` 컨텍스트(별도 `proxy_method GET;` 지정)를 위한 것이며, auth_request 전용 권고가 아니다. auth_request 서브리퀘스트 맥락에서의 필수 여부는 별도 자료(`nginx-auth-request-module-official.md`, `oauth2-proxy-nginx-integration-official.md`)가 담당한다. 또한 이 예제가 모든 `proxy_pass_request_body off;` 사용에 `Content-Length ""` 짝짓기가 항상 필요하다는 일반 규칙을 선언한 것도 아니다 — 하나의 예시일 뿐이다. | + +### Strength 허용값 참고 + +- 두 claim 모두 `official-vendor-doc` — nginx(F5) 공식 reference 문서의 directive 항목 및 공식 예제이며, 표준 사양(RFC)이 아니므로 `official-standard` 아님. + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `NGXPM-C1`: `proxy_pass_request_body` 의 기본값이 `on` 이고, 이 directive 가 원본 request body 전달 여부를 제어한다는 사실 (syntax / default / context / description 4종 세트). + - `NGXPM-C2`: 공식 문서가 `off` + `Content-Length ""` 조합을 예제로 제시한다는 사실 (X-Accel-Redirect 스타일 location 한정). +- **이 자료가 증명하지 않는 것**: + - auth_request subrequest 가 반드시 `proxy_pass` 기반 location 으로 라우팅된다는 것 (subrequest 목적지가 다른 handler 일 경우 이 directive 자체가 무관할 수 있음). + - `off` + `Content-Length ""` 조합이 auth_request 서브리퀘스트에 대해 공식적으로 "필수"라는 것 — 그 전용 권고는 이 raw 의 역할이 아니며 `nginx-auth-request-module-official.md` / `oauth2-proxy-nginx-integration-official.md` 가 담당. + - `off` 하지 않을 때(default `on`) auth_request subrequest 로 실제 POST body 가 전달되어 어떤 부작용(oauth2-proxy CPU 증가, 의도치 않은 endpoint 트리거 등)이 발생하는지 — 이는 본 문서 범위 밖의 추론이며 D6 Open Risk 로 별도 관리. +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - `/oauth2/auth` internal location 이 실제로 `proxy_pass` 로 oauth2-proxy upstream 에 연결되는지 (본 branch TODO 기준으로는 그렇다고 가정되어 있음). + - `off` 설정 후 실제 nginx 로그에서 body 가 upstream 으로 전달되지 않는지 로컬 검증 (`Claims To Verify` 대상). + +## 메모 / Notes + +> 본 섹션은 자료 직접 인용 아님. D6 결정 컨텍스트 해석. + +- 이 raw 는 D6 을 `UNSUPPORTED_DECISION` → `official-vendor-doc` 근거 있는 결정으로 승급시키는 **메커니즘 근거**일 뿐, "auth_request 에 필수"라는 전용 권고 근거는 별도 자료 몫이다. branch-note 의 Decision Evidence Map D6 행 갱신 시 Supporting Claims 를 `NGXPM-C1`, `NGXPM-C2` 로 채우되 Open Risk 에 "auth_request 필수 여부는 별도 raw 필요" 를 남겨야 한다. +- 추가로 봐야 할 동일 출처 페이지: `ngx_http_proxy_module.html#proxy_pass_request_headers` (같은 페이지, sibling directive — 헤더 전달 여부를 별도로 제어하며 동일 예제 패턴에서 함께 등장). + +## Related / 관련 + +- 같은 주제 다른 official-doc: + - [[raw/official-docs/nginx-auth-request-module-official]] — `auth_request` directive 자체의 응답코드 규약 (subrequest 가 어디로 라우팅되는지는 이 문서가 다루지 않음) + - [[raw/official-docs/oauth2-proxy-nginx-integration-official]] — oauth2-proxy 측 `/oauth2/auth` nginx 통합 가이드 (auth_request 서브리퀘스트 전용 권고 담당) +- 인용하는 wiki: (미작성) diff --git a/vault/20-evidence/official-docs/react-router-official.md b/vault/20-evidence/official-docs/react-router-official.md new file mode 100644 index 0000000..a803d2b --- /dev/null +++ b/vault/20-evidence/official-docs/react-router-official.md @@ -0,0 +1,90 @@ +--- +title: official-doc / React Router — Declarative Mode Routing Guide (Routes, Nested Routes, Navigation) +source_type: official-doc +url: https://reactrouter.com/start/library/routing +archive_url: +related_branches: [] +related_projects: [ca-skeleton-frontend] +tags: [official-doc, ca-skeleton, frontend, react] +created: 2026-07-18 +--- + +# official-doc / React Router — Declarative Mode Routing Guide (Routes, Nested Routes, Navigation) + +> Layer: `raw/` — 외부 자료(공식 문서)의 원문 발췌·출처 기록. + +## source_type + +`official-doc` — React Router 공식 문서 (reactrouter.com). + +## Parent / 활용 branch + +> 특정 branch 없이 project 차원의 foundational 조사로 수집 (`ca-skeleton-frontend` 의 라우팅 + navigation-guard 계약을 세우기 전 기술 선정 근거). + +| Parent | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/project-notes/ca-skeleton-frontend-operational-contract]] | client-only Vite SPA 에서 React Router 를 라우팅 + navigation 제어 라이브러리로 채택하는 근거 — ``/`` 컴포넌트 트리로 route 를 선언하고 (파일 기반 프레임워크 컨벤션 없이), nested route 는 `` 로 합성하며, `Link`/`NavLink` 로 클라이언트 사이드 네비게이션을 제어하는 "Declarative Mode" 형태가 SSR/프레임워크 컨벤션이 필요 없는 Vite-SPA 구조에 부합함을 뒷받침 | + +## 출처 / Source + +- 원본 URL: https://reactrouter.com/start/library/routing +- 아카이브 URL: (미제공) +- 저자 / 조직: React Router 공식 문서 (reactrouter.com) +- 발행일: 미상 (문서 자체에 발행일 명시 없음; 본문 상 버전 표기 "React Router v8.2.0" 확인) +- 마지막 확인일: 2026-07-18 + +**참고**: 요청 URL 경로는 `/start/library/routing` ("library" 라는 표현 포함) 이었으나, WebFetch 로 실제 가져온 본문 타이틀·본문은 "React Router Declarative Mode: Routing Guide" 로 명명되어 있고, 본문 스스로 이 모드를 **"Declarative Mode"** 라고 부른다 (Framework Mode / Data Mode 와 구분 — 아래 §핵심 인용 5번 참조). URL 슬러그의 "library" 와 본문의 "Declarative Mode" 표현이 정확히 동일 용어는 아니므로, 이 둘이 같은 개념이라는 추가 해석은 본 raw 문서에서 단정하지 않는다 (검증되지 않은 추론이므로 §메모 에도 남기지 않음 — wiki 승격 시 별도 확인 필요). + +## 왜 저장했는지 / Why archived + +`ca-skeleton-frontend` 는 client-only SPA (Vite 빌드, SSR/프레임워크 컨벤션 없음) 이므로, 라우팅 라이브러리가 파일 기반 프레임워크 규약이나 서버 loader 없이도 route 정의·중첩·네비게이션 제어를 지원하는지 공식 근거로 확인하기 위해 저장. React Router 의 route 선언 API (``/``), nested route 합성(``), 네비게이션 컴포넌트(`Link`/`NavLink`) 가 이 요구를 충족하는지가 이 자료의 핵심 확인 대상. + +## 핵심 인용 / Key quotes (verbatim) + +> [§Configuring Routes] "Routes are configured by rendering `` and `` components that couple URL segments to UI elements:" — line 9 (fetched text) + +> [§Nested Routes] "Routes can be nested inside parent routes. The parent's path is automatically included in children:" — line 30 (fetched text) + +> [§Nested Routes] "Child routes render through the `` component in the parent:" — line 41 (fetched text) + +> [§Navigation] "**Key difference:** `NavLink` automatically applies active state styling, while `Link` is a basic navigation element." — line 134 (fetched text) + +> [문서 하단, mode 구분] "This is **Declarative Mode**, distinct from Framework Mode (file-based routing with conventions) and Data Mode (route objects with data loading/actions)." — line 138 (fetched text) + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| REACT-ROUTER-C1 | React Router 는 ``/`` 컴포넌트를 렌더링해 URL segment 를 UI element 에 결합하는 방식으로 route 를 선언적으로 구성한다 | [§Configuring Routes] "Routes are configured by rendering `` and `` components that couple URL segments to UI elements:" | `official-vendor-doc` | client-side component-tree 기반 route 선언 (파일 기반 프레임워크 컨벤션 불필요) | 성능·번들 크기·프로덕션 준비도는 증명하지 않음. Framework Mode/Data Mode 와의 상세 차이는 이 인용만으로 증명 안 됨 | +| REACT-ROUTER-C2 | 부모 route 안에 자식 route 를 중첩할 수 있고, 부모의 path 가 자식에 자동 포함되며, 자식 route 는 부모 컴포넌트의 `` 을 통해 렌더링된다 | [§Nested Routes] "Routes can be nested inside parent routes. The parent's path is automatically included in children:" + "Child routes render through the `` component in the parent:" | `official-vendor-doc` | 레이아웃 + 자식 페이지 합성 패턴 (예: 인증된 레이아웃 아래 보호된 페이지들을 중첩) | 데이터 로딩(loader)·인가(auth) 로직이 이 중첩 메커니즘에 어떻게 결합되는지는 증명하지 않음 (이는 Data Mode/Framework Mode 영역) | +| REACT-ROUTER-C3 | `NavLink` 는 활성 상태 스타일링을 자동 적용하고, `Link` 는 기본 네비게이션 엘리먼트라는 점에서 서로 다르다 | [§Navigation] "**Key difference:** `NavLink` automatically applies active state styling, while `Link` is a basic navigation element." | `official-vendor-doc` | 클라이언트 사이드 네비게이션 UI (예: 메뉴 활성 항목 하이라이트) | **navigation guard(인증/인가 기반 라우트 보호) 메커니즘은 증명하지 않음** — 이 인용은 활성 링크 스타일링에 관한 것이며, 라우트 접근 제어(redirect/guard) 로직에 대한 근거가 아님. `ca-skeleton-frontend` 의 navigation-guard 계약에 이 자료를 직접 인용하려면 별도 loader/guard 관련 공식 문서 보강 필요 | +| REACT-ROUTER-C4 | 본 문서가 다루는 라우팅 방식은 "Declarative Mode" 로 명명되며, 파일 기반 컨벤션을 쓰는 "Framework Mode" 및 데이터 로딩/액션을 route 객체로 다루는 "Data Mode" 와 구분된다 | [문서 하단] "This is **Declarative Mode**, distinct from Framework Mode (file-based routing with conventions) and Data Mode (route objects with data loading/actions)." | `official-vendor-doc` | SSR/파일 기반 프레임워크 컨벤션이 필요 없는 client-only Vite SPA 에 적합한 라우팅 모드 선택의 근거 | Declarative Mode 가 Data Mode 대비 프로덕션에 "권장"된다는 것은 증명하지 않음. 세 모드 간 성능·기능 parity 도 증명하지 않음 | + +### Strength 근거 + +모든 claim 이 `official-vendor-doc` — reactrouter.com 은 React Router 프로젝트의 공식 문서 사이트이며, 벤더(라이브러리 메인테이너)가 직접 게시하는 레퍼런스 문서. + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `REACT-ROUTER-C1`: ``/`` 컴포넌트 기반 선언적 route 정의 API 존재 + - `REACT-ROUTER-C2`: nested route + `` 합성 메커니즘 존재 + - `REACT-ROUTER-C3`: `Link` vs `NavLink` 의 활성 스타일링 차이 존재 + - `REACT-ROUTER-C4`: "Declarative Mode" 가 "Framework Mode"(파일 기반 SSR 컨벤션)와 별개로 존재 — 즉 프레임워크 컨벤션 없이도 라우팅을 구성할 수 있음 +- 이 자료가 증명하지 않는 것: + - **navigation guard(인증 기반 라우트 보호) 메커니즘의 존재나 구현 방식** — 본 발췌에는 loader, redirect, protected-route 패턴에 대한 언급이 전혀 없음. `ca-skeleton-frontend` 의 navigation-guard 결정에는 이 자료만으로 충분한 근거가 아니며, 별도 공식 자료(loader/redirect 또는 인증 가드 관련 문서) 보강 필요 — `UNSUPPORTED_DECISION` 후보 + - 프로덕션 성능/번들 크기/타 라우팅 라이브러리(TanStack Router 등) 대비 우위 + - "library mode" 라는 명칭이 "Declarative Mode" 와 동일 개념이라는 것 (§출처 참고 항목 참조 — 미확인) +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - `ca-skeleton-frontend` 의 실제 route 트리 설계와 이 API 의 정합성 로컬 검증 + - 인증/인가 기반 navigation guard 구현 시 별도 loader/redirect 공식 문서 확보 + +## 메모 / Notes + +- REACT-ROUTER-C3 는 "네비게이션 제어"의 UI 측면(활성 스타일)만 다루며, 이 문서만으로 "navigation guard"(보호된 라우트) 계약을 정당화할 수 없음 — branch-note 작성 시 이 구분을 명확히 유지할 것. +- 추가로 봐야 할 동일 출처 페이지: loader/action 기반 데이터 로딩 및 redirect 패턴을 다루는 React Router 공식 문서 (별도 raw 자료로 추가 필요 — navigation-guard 결정의 직접 근거). + +## Related / 관련 + +- 같은 주제 다른 official-doc: (없음 — 이 자료가 vault 내 첫 React Router 공식 문서) +- 이 자료를 인용한 wiki 요약: (아직 생성 안 됨) diff --git a/vault/20-evidence/official-docs/react-ui-library-official.md b/vault/20-evidence/official-docs/react-ui-library-official.md new file mode 100644 index 0000000..7d49654 --- /dev/null +++ b/vault/20-evidence/official-docs/react-ui-library-official.md @@ -0,0 +1,87 @@ +--- +title: React Official Docs — Quick Start (Component Model) +source_type: official-doc +url: https://react.dev/learn +archive_url: +related_branches: [] +related_projects: [ca-skeleton-frontend] +tags: [official-doc, ca-skeleton, frontend, react] +created: 2026-07-18 +--- + +# React Official Docs — Quick Start (Component Model) + +> Layer: `raw/` — 외부 자료(공식 문서)의 **원문 발췌·출처 기록**. + +## source_type 허용값 + +- `official-doc` — React 공식 문서 (react.dev, Meta 유지보수) + +## Parent / 활용 branch (필수, 최소 1개+) + +특정 branch 없이 foundational 조사로 수집한 경우: + +- [[raw/project-notes/ca-skeleton-frontend-operational-contract]] — component-based SPA skeleton 을 만들 UI 기술로 React 를 채택하는 결정("프레임워크 / 기술 결정" §6)의 초기 근거 자료. component 모델(함수형 컴포넌트, JSX, props/state 로 데이터 전달)이 skeleton 의 컴포넌트 구성 방식을 규정. + +## 출처 / Source + +- 원본 URL: https://react.dev/learn +- 아카이브 URL: (미확보) +- 저자 / 조직: Meta (React core team) — react.dev 공식 문서 +- 발행일: (react.dev 는 지속 갱신되는 living doc — 발행일 명시 없음) +- 마지막 확인일: 2026-07-18 + +## 왜 저장했는지 / Why archived + +`ca-skeleton-frontend` 프로젝트가 client-only SPA(서버 런타임 없음) 스켈레톤을 만들 때 React 의 **컴포넌트 모델**(함수형 컴포넌트가 markup 반환, 컴포넌트 nesting, props 를 통한 단방향 데이터 흐름)이 skeleton 의 컴포넌트 분해·재사용 방식을 정당화하는 1차 근거. `/learn` 페이지는 React 공식 Quick Start 로 daily-use 개념의 80%를 다룬다고 명시한 진입점 문서. + +## 핵심 인용 / Key quotes (verbatim, 5문장) + +> [Creating and Nesting Components] "React apps are built from **components** - pieces of UI with their own logic and appearance, ranging from buttons to entire pages." (line 18 in fetched text) + +> [Creating and Nesting Components] "React components are JavaScript functions that return markup:" (line 20 in fetched text) + +> [Creating and Nesting Components] "Components can be nested into other components:" (line 30 in fetched text) + +> [Creating and Nesting Components] "**Important:** React component names must start with a capital letter. HTML tags must be lowercase." (line 43 in fetched text) + +> [Sharing Data Between Components] "Pass state down as **props** to child components. When the parent state changes, all children receive the updated values." (line 288 in fetched text) + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| REACT-UI-C1 | React 앱은 자기만의 로직과 외형을 가진 재사용 가능한 "컴포넌트" 단위로 구성된다 (버튼부터 전체 페이지까지 스케일이 다양) | "React apps are built from **components** - pieces of UI with their own logic and appearance, ranging from buttons to entire pages." | `official-vendor-doc` | 컴포넌트 기반 UI 분해가 React 의 핵심 구성 단위라는 사실 | component-based 접근이 다른 라이브러리(Vue, Svelte 등) 대비 우월하다는 것은 증명하지 않음 | +| REACT-UI-C2 | React 컴포넌트는 markup 을 반환하는 JavaScript 함수로 정의된다 | "React components are JavaScript functions that return markup:" | `official-vendor-doc` | 함수형 컴포넌트가 React 의 표준 정의 방식이라는 사실(현재 공식 가이드 기준) | class 컴포넌트가 deprecated 되었는지 여부는 이 인용만으로 증명 안 됨 | +| REACT-UI-C3 | 컴포넌트는 다른 컴포넌트 안에 중첩(nest)될 수 있다 | "Components can be nested into other components:" | `official-vendor-doc` | 컴포넌트 합성(composition)을 통한 UI 트리 구성 가능성 | 중첩 depth 제한이나 성능 특성은 증명하지 않음 | +| REACT-UI-C4 | 컴포넌트 이름은 대문자로 시작해야 하고 HTML 태그는 소문자여야 한다 (JSX 파서가 둘을 구분하는 문법 규칙) | "**Important:** React component names must start with a capital letter. HTML tags must be lowercase." | `official-vendor-doc` | JSX 문법 상 컴포넌트/HTML 태그 구분 규칙 | 이 규칙의 내부 구현(reconciler) 원리는 설명하지 않음 | +| REACT-UI-C5 | 부모 컴포넌트의 상태(state)는 props 로 자식 컴포넌트에 전달되며, 부모 상태가 바뀌면 모든 자식이 갱신된 값을 받는다 (단방향 데이터 흐름) | "Pass state down as **props** to child components. When the parent state changes, all children receive the updated values." | `official-vendor-doc` | 단방향(top-down) 데이터 흐름이 React 의 기본 데이터 전달 모델이라는 사실 | 전역 상태관리(Redux, Context API 등) 도구 없이 대규모 앱에서 이 패턴만으로 충분한지는 증명하지 않음 | + +### Strength 참고 + +React 공식 사이트(react.dev)는 Meta 가 직접 유지보수하는 official-vendor-doc 이므로 위 모든 claim 은 `official-vendor-doc` 로 분류. RFC/표준 수준(`official-standard`)은 아님 — React 는 표준 사양이 아니라 특정 벤더(Meta)의 라이브러리 구현체. + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `REACT-UI-C1`~`REACT-UI-C3`: React 의 컴포넌트 모델(함수 컴포넌트 + nesting + composition) + - `REACT-UI-C4`: JSX 문법 규칙(컴포넌트/HTML 태그 대소문자 구분) + - `REACT-UI-C5`: props 를 통한 단방향 데이터 흐름 +- 이 자료가 증명하지 않는 것: + - **"React 는 라이브러리이지 프레임워크가 아니다"라는 명시적 진술은 이 fetch 범위(`/learn` Quick Start 페이지)에서 발견되지 않음.** 2차 WebFetch(targeted prompt)로 재확인했으나 해당 문장은 `/learn` 페이지 밖(예: "Start a New React Project" 또는 별도 개요 페이지)에 있을 가능성이 높고, 이번 dispatch 범위에서는 self-grep 통과 가능한 verbatim 인용을 확보하지 못했다. **`UNSUPPORTED_DECISION`** — "라이브러리 vs 프레임워크" 근거로 이 문서를 인용하지 말 것. 별도 URL(예: react.dev 개요 페이지 또는 "Start a New React Project" 섹션)에 대한 후속 `wiki-source-summarizer` dispatch 필요. + - "declarative UI" 라는 표현 자체도 이번 fetch 범위에서 확인되지 않음 (동일하게 후속 조사 필요). + - React 가 "client-only SPA, no server runtime" 결정에 필수적이라는 주장은 증명하지 않음 — 이 문서는 컴포넌트 모델만 설명하며, 서버 런타임 유무는 React 자체와 독립적인 배포 방식 선택(SSR/SSG 프레임워크 사용 여부)의 문제. + - 성능, 번들 크기, 생태계 비교(Vue/Svelte/Angular 대비)는 다루지 않음. +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - `ca-skeleton-frontend` 의 실제 컴포넌트 트리 설계가 이 가이드의 nesting/props 패턴을 따르는지 로컬 검증 필요. + - "라이브러리 vs 프레임워크" 및 "declarative" 공식 진술은 별도 react.dev 페이지(개요/철학 섹션)에서 재조사 후 별도 raw 문서 또는 본 문서 보강 필요. + +## 메모 / Notes + +- 인용 1 해석 후보 (미검증): 컴포넌트가 "버튼부터 전체 페이지까지" 스케일 가능하다는 서술은 skeleton 의 atomic-to-page 컴포넌트 계층 설계에 참고 가능해 보이나, 이 자료 자체가 계층 설계 방법론을 규정하진 않음. +- 추가로 봐야 할 동일 출처 페이지: react.dev 개요/철학 페이지(라이브러리 vs 프레임워크 진술), `/learn/thinking-in-react`(컴포넌트 분해 방법론), `/learn/describing-the-ui`(declarative 표현이 있을 가능성). + +## Related / 관련 + +- 같은 주제 다른 official-doc / company-tech-blog: (현재 없음 — 첫 React 관련 raw 자료) +- 이 자료를 인용한 wiki 요약: `[[wiki/concepts/...]]` (생성 시) diff --git a/vault/20-evidence/official-docs/redhat-openjdk-container-awareness-java17.md b/vault/20-evidence/official-docs/redhat-openjdk-container-awareness-java17.md new file mode 100644 index 0000000..1f5a0d7 --- /dev/null +++ b/vault/20-evidence/official-docs/redhat-openjdk-container-awareness-java17.md @@ -0,0 +1,90 @@ +--- +title: "Java 17: What's new in OpenJDK's container awareness (Red Hat Developer)" +source_type: official-doc +url: https://developers.redhat.com/articles/2022/04/19/java-17-whats-new-openjdks-container-awareness +archive_url: +related_branches: [feature-container-runtime-contract] +related_projects: [ca-skeleton] +tags: [official-doc, ca-skeleton, runtime, kubernetes, thread-pool] +created: 2026-06-14 +--- + +# Java 17: What's new in OpenJDK's container awareness (Red Hat Developer) + +> Layer: `raw/` — 외부 자료(공식 문서 / 대기업 기술 블로그)의 **원문 발췌·출처 기록**. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 `source-summary-template` 형식으로 별도 작성. 원본은 raw에 영구 보관. + +## Parent / 활용 branch + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-container-runtime-contract]] | **D4** — `-XX:MaxRAMPercentage=75` rationale: Red Hat (primary OpenJDK contributor/LTS steward) documents that `MaxRAMPercentage` is the percentage of container memory limit (default 25%), the cgroup v1/v2 support boundaries by JDK version, and how container limits drive heap/GC/thread-pool ergonomics. | + +## 출처 / Source + +- 원본 URL: https://developers.redhat.com/articles/2022/04/19/java-17-whats-new-openjdks-container-awareness +- 아카이브 URL: (미등록 — archive.org 스냅샷 보강 권고) +- 저자 / 조직: Red Hat Developer (primary OpenJDK contributor / Eclipse Temurin LTS steward) +- 발행일: 2022-04-19 +- 마지막 확인일: 2026-06-14 + +## 왜 저장했는지 / Why archived + +`feature-container-runtime-contract` D4 결정(`-XX:MaxRAMPercentage=75`)의 근거 부재를 해소하기 위해 보관. Red Hat은 OpenJDK 주요 기여자이자 Eclipse Temurin LTS 스튜어드로서, `MaxRAMPercentage`의 기본값(25%), cgroup v1/v2 지원 JDK 버전 경계, 그리고 container 제한이 GC 알고리즘 선택·기본 heap 크기·thread pool·ForkJoinPool 병렬성에 미치는 영향을 직접 문서화하고 있다. + +## 핵심 인용 / Key quotes (verbatim, 3~5문장) + +> [§Key Tuning Options] "Maximum percentage of real memory used for maximum heap size. Default value: 25" + +> [§cgroups v2 Support] "Since Java 15, OpenJDK detects the cgroup version in use and detects limits according to cgroup version-specific settings." + +> [§cgroups v2 Support] "As of this writing, OpenJDK 17, OpenJDK 11.0.16+ and OpenJDK 8u372+ are the only long-term support releases that support both cgroups v1 and cgroups v2 configurations." + +> [§Why Container Awareness Matters / Resource limits] "OpenJDK detects whether certain resource quotas are in place when running in a container and, if so, uses those bounds for its operation. These resource limits affect, for example, the garbage collection (GC) algorithm selected by the JVM, the default size of the heap, the sizes of thread pools, and how default parallelism is determined for `ForkJoinPool`." + +## Claims Extracted / 추출된 주장 + +> 이 자료가 **직접 말하는 것만** claim 으로 분리한다. 내 프로젝트에 적용한 결론은 여기 쓰지 않는다. +> Red Hat은 OpenJDK 주요 기여자(vendor)이나 본 문서는 Red Hat의 분석이며 중립적 사양(spec)이 아님. + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| RHAT-JCONT-C1 | `-XX:MaxRAMPercentage` 의 기본값은 25%이며, 이는 container 또는 real memory 의 최대 heap 비율을 설정한다 | [§Key Tuning Options] "Maximum percentage of real memory used for maximum heap size. Default value: 25" | `official-vendor-doc` | OpenJDK 17 (본 문서의 대상 버전), `UseContainerSupport` 활성 환경 | 75%가 최적값임을 증명하지 않음; 기본값 25%에서 75%로 올리는 것이 항상 안전함을 증명하지 않음 | +| RHAT-JCONT-C2 | Java 15부터 OpenJDK는 사용 중인 cgroup 버전을 자동 감지하고 버전별 설정에 따라 limit 을 인식한다 | [§cgroups v2 Support] "Since Java 15, OpenJDK detects the cgroup version in use and detects limits according to cgroup version-specific settings." | `official-vendor-doc` | OpenJDK 15 이상 | Java 15 미만은 해당 없음; 모든 cgroup v2 설정이 자동으로 올바르게 감지됨을 보장하지 않음 | +| RHAT-JCONT-C3 | cgroup v1 및 v2 모두 지원하는 LTS 버전은 OpenJDK 17, 11.0.16+, 8u372+뿐이다 (본 문서 작성 시점 기준) | [§cgroups v2 Support] "As of this writing, OpenJDK 17, OpenJDK 11.0.16+ and OpenJDK 8u372+ are the only long-term support releases that support both cgroups v1 and cgroups v2 configurations." | `official-vendor-doc` | 2022-04-19 시점 기준 OpenJDK LTS 버전 | 이후 버전(21, 25 등)의 cgroup v2 지원 여부는 이 문서만으로 판단 불가; "as of this writing" 표현으로 시점 한정 | +| RHAT-JCONT-C4 | container 내 resource limit(cgroup)은 JVM이 선택하는 GC 알고리즘, 기본 heap 크기, thread pool 크기, ForkJoinPool 병렬성 기본값에 직접 영향을 미친다 | [§Why Container Awareness Matters] "OpenJDK detects whether certain resource quotas are in place when running in a container and, if so, uses those bounds for its operation. These resource limits affect, for example, the garbage collection (GC) algorithm selected by the JVM, the default size of the heap, the sizes of thread pools, and how default parallelism is determined for `ForkJoinPool`." | `official-vendor-doc` | `UseContainerSupport` 활성 상태(JDK 10+ 기본값)인 모든 컨테이너 환경 | 정확한 GC 알고리즘 선택 임계값이나 thread pool 산식 자체를 이 문서가 명시하지는 않음 | + +### Strength 허용값 (참고) + +- `official-vendor-doc` — Spring, Keycloak, AWS, Google, Red Hat 등 공식 벤더 문서 (본 문서 적용) + +> **주의**: 이 문서는 Red Hat의 OpenJDK 분석 아티클이며, OpenJDK 공식 사양(JEP, JDK Release Notes)과는 별개다. Claims는 `official-vendor-doc` 강도이며, `official-standard`가 아님. 75%를 선택한 것은 D4의 team 결정이고, 본 문서는 "기본값이 25%"임과 "container limit이 ergonomics에 영향을 준다"는 사실만 지지한다. + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `RHAT-JCONT-C1`: `-XX:MaxRAMPercentage` 기본값이 25%이며 container/real memory 비율로 작동함 + - `RHAT-JCONT-C2`: Java 15부터 cgroup 버전 자동 감지가 OpenJDK 기본 동작 + - `RHAT-JCONT-C3`: cgroup v1+v2 동시 지원 LTS = OpenJDK 17, 11.0.16+, 8u372+ (2022년 4월 기준) + - `RHAT-JCONT-C4`: cgroup resource limit이 GC 알고리즘·heap·thread pool·ForkJoinPool 결정에 영향을 줌 +- 이 자료가 증명하지 않는 것: + - 75%가 최적 또는 안전한 `MaxRAMPercentage` 값임 (D4의 75% 선택은 team-convention) + - Java 21+에서의 cgroup v2 지원 세부 사항 (2022년 발행 문서이므로 시점 한정) + - `UseContainerSupport`를 명시하지 않을 때의 기본 활성 여부 (JDK 10+ 기본값이라는 내용은 본 문서에서 명시되나, 특정 배포판 변형에서의 동작 보장은 별도 확인 필요) +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - ca-tmpl/ca-skeleton 실제 container 환경에서 `-XX:MaxRAMPercentage=75` 적용 시 `Runtime.getRuntime().maxMemory()`가 container limit의 75%로 설정되는지 `locally-verified` 등급 테스트 필요 (`Claims To Verify` 항목) + - Eclipse Temurin 배포판 기준 `UseContainerSupport` 기본값 활성 확인 (OpenJDK contributor로서 Red Hat 문서가 근거가 되나, Temurin 공식 릴리즈 노트로 교차 확인 권고) + +## 메모 / Notes + +- 본 아티클은 2022-04-19 발행. Java 21 LTS (2023-09-19)와 그 이후 버전의 cgroup 지원 세부 내용은 이 문서로 커버되지 않는다. JDK 21+ 용 별도 source 보강 권고. +- `RHAT-JCONT-C1`이 D4(75% 결정)의 직접 근거: "기본값이 25%인데 우리는 75%를 선택했다"는 의사결정 맥락을 뒷받침. 75% 선택의 근거 자체는 team 경험치 기반이므로 `UNSUPPORTED_DECISION` 라벨이 D4에 남아있는 것이 적절하다 — 본 source는 "값의 의미와 기본값"을 증명하며, "75%가 왜 최적인가"는 추가 벤치마크 또는 Red Hat production guidance 등이 필요. +- 추가로 봐야 할 동일 출처 페이지: Red Hat JDK 17 release blog, Eclipse Temurin 공식 container guidance, OpenJDK JEP 관련 문서. + +## Related / 관련 + +- 같은 주제 다른 official-doc / company-tech-blog: + - [[raw/official-docs/container-distroless-google-github]] — base image 선택 근거 + - [[raw/official-docs/container-alpine-java-musl-tradeoffs]] — Alpine + musl 대안 + - [[raw/official-docs/container-graalvm-native-image-spring-boot]] — GraalVM Native Image 대안 +- 이 자료를 인용한 wiki 요약: (생성 시 추가 예정) diff --git a/vault/20-evidence/official-docs/registry-adr-official.md b/vault/20-evidence/official-docs/registry-adr-official.md new file mode 100644 index 0000000..39fe790 --- /dev/null +++ b/vault/20-evidence/official-docs/registry-adr-official.md @@ -0,0 +1,97 @@ +--- +title: Architecture Decision Records (ADR) — 공식 사이트 +source_type: official-doc +url: https://adr.github.io/ +archive_url: +status: raw +confidence: high +tags: [adr, governance, registry, decision-record, ca-skeleton, official-doc] +related_projects: [ca-skeleton-operational-contract] +related_branches: [feature-contract-registry-governance, feature-implementation-readiness-scorecard] +created: 2026-05-22 +last_reviewed: 2026-05-27 +--- + +# Architecture Decision Records (ADR) — 공식 사이트 + +> Layer: `raw/official-docs/` — adr.github.io 공식 사이트 발췌. registry governance/scorecard 의 "결정 사항" 섹션을 ADR 포맷으로 보완할지 평가용. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-contract-registry-governance]] | ADR (Nygard/MADR) 가 registry 의 "결정 사항" 라인과 어떻게 매핑되는지 비교 근거 | +| [[raw/branch-notes/feature-implementation-readiness-scorecard]] | scorecard "결정 사항 누적" 모델과 ADR 의 1-decision-1-file 모델의 trade-off 비교 | + +## 컨텍스트 + +`feature-contract-registry-governance`와 `feature-implementation-readiness-scorecard`는 **결정 사항**을 누적한다. ADR 포맷(Nygard 또는 MADR)이 본 skeleton의 "결정 사항(decisions)" 섹션과 어떻게 매핑되는지, registry 변경 절차의 단계 1–6에 ADR을 끼울 가치가 있는지 평가하려고 보관. + +## 출처 / Source + +- 원본 URL: https://adr.github.io/ +- 아카이브 URL: (미수집) +- 저자/조직: ADR community (originally Michael Nygard, 2011) +- 발행일: 지속적으로 갱신 +- 마지막 확인일: 2026-05-27 + +## 핵심 인용 / Key quotes (verbatim) + +> [§What is an Architectural Decision] "An Architectural Decision (AD) is a justified design choice that addresses a functional or non-functional requirement that is architecturally significant." + +> [§What is an ADR] "An Architectural Decision Record (ADR) captures a single AD and its rationale; Put it simply, ADR can help you understand the reasons for a chosen architectural decision, along with its trade-offs and consequences." + +> [§History / popularization] "Documenting Architecture Decisions is the blog post from 2011 by Michael Nygard that popularized the concept." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| REG-ADR-C1 | Architectural Decision (AD) 는 architecturally significant 한 functional/non-functional requirement 를 다루는 정당화된 design choice 이다 | [§What is an Architectural Decision] "An Architectural Decision (AD) is a justified design choice that addresses a functional or non-functional requirement that is architecturally significant." | `official-reference` | 결정 사항이 "AD" 로 분류되는 조건 정의 | 모든 결정이 AD 라는 뜻은 아님 — "architecturally significant" 판정 기준은 별도 | +| REG-ADR-C2 | ADR (Architectural Decision Record) 는 단일 AD 와 그 rationale 을 기록하며, 선택의 이유 / trade-offs / consequences 를 함께 포함한다 | [§What is an ADR] "An Architectural Decision Record (ADR) captures a single AD and its rationale; Put it simply, ADR can help you understand the reasons for a chosen architectural decision, along with its trade-offs and consequences." | `official-reference` | ADR 파일 1개당 결정 1개 모델 채택 평가 | 결정의 "재평가/철회" 처리가 같은 파일 수정인지 새 ADR 발행인지는 본 인용에 명시 없음 (Status 필드 별도) | +| REG-ADR-C3 | Michael Nygard 의 2011 블로그 글 "Documenting Architecture Decisions" 가 ADR 개념을 대중화시킨 출처이다 | [§History] "Documenting Architecture Decisions is the blog post from 2011 by Michael Nygard that popularized the concept." | `official-reference` | ADR 개념의 origin 식별 | 해당 글이 정의한 정확한 4-section 템플릿 (Status/Context/Decision/Consequences) 이 공식 표준임을 본 페이지가 직접 명시하지는 않음 — 본문은 Y-statement 등 다른 변형도 언급 | + +### Strength 허용값 사용 + +- `official-reference` — adr.github.io 는 ADR 커뮤니티의 공식 reference 사이트 (단, 단일 벤더 제품 문서가 아니라 community-curated reference 이므로 `official-vendor-doc` 가 아닌 `official-reference` 로 분류) + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `REG-ADR-C1`: AD 의 정의 (architecturally significant 한 design choice + 정당화) + - `REG-ADR-C2`: ADR 의 정의 (1 AD + rationale + trade-offs + consequences) + - `REG-ADR-C3`: Nygard 2011 blog 가 popularization origin +- **이 자료가 증명하지 않는 것**: + - Nygard 의 정확한 4-section (Status, Context, Decision, Consequences) 템플릿이 **공식 표준** 이라는 사실 — 본 페이지는 해당 4 섹션을 verbatim 으로 명시하지 않음. 4-section 은 Nygard 원문(2011) 또는 별도 도구 (adr-tools) 에 기재됨 + - MADR (Markdown Any Decision Records) 의 구체적 schema + - ADR 을 registry 와 함께 쓸 때 변경 절차에 끼울 정확한 위치 (이는 본 wiki 의 자체 결정) +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - Nygard 원문 (2011 blog) 의 verbatim 4-section 정의 확인 (보조 source 필요) + - MADR 공식 spec 비교 (별도 raw 자료) + - ca-tmpl 의 branch-note 가 이미 mini-ADR 역할을 하므로 ADR 별도 파일이 중복인지 비-중복인지 결정 (본 wiki 결정 영역, source 가 증명하지 않음) + +## 메모 / Notes (내 프로젝트 해석) + +> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석. + +- 본 skeleton의 branch note는 사실상 **branch당 mini-ADR + Work Item Contract 표**. Status는 `status_label`, Context는 "목표/WHY", Decision은 "결정 사항", Consequences는 "테스트 계약 + Failure condition". +- 즉 ADR 별도 파일을 또 만드는 것은 중복. **결정 사항 라인이 곧 ADR id로 작동**할 수 있다 (예: `2026-05-22: registry row의 공통 필수 column은 ...`). +- ADR을 별도 도입한다면 registry **변경 절차의 step 1.5**로 "ADR row 작성"을 추가하는 형태가 자연스러움. +- 결론: ADR은 alternative source로 인용은 하되, ca-tmpl 결정으로 **별도 ADR 파일 생성은 out-of-scope** 권장. + +## 관련 ca-tmpl branch / contract + +- 적용 branch-note: + - [[raw/branch-notes/feature-contract-registry-governance]] +- canonical contract 섹션: + - [[raw/project-notes/ca-skeleton-operational-contract#21. Contract Registry]] +- 대안 그룹: **Group G-G — Skeleton Governance** (registry governance) +- 본 source의 위치: 대안 1 — ADR (Architectural Decision Record) 별도 파일 + +## Related / 관련 + +- 같은 주제 다른 official-doc: (미수집 — Nygard 2011 원문, MADR spec 후보) +- 인용하는 branch: + - [[raw/branch-notes/feature-contract-registry-governance]] + - [[raw/branch-notes/feature-implementation-readiness-scorecard]] +- 인용하는 wiki: (미작성) diff --git a/vault/20-evidence/official-docs/renovate-gradle-manager-official.md b/vault/20-evidence/official-docs/renovate-gradle-manager-official.md new file mode 100644 index 0000000..290b74a --- /dev/null +++ b/vault/20-evidence/official-docs/renovate-gradle-manager-official.md @@ -0,0 +1,87 @@ +--- +title: Renovate Gradle Manager — Official Documentation +source_type: official-doc +url: https://docs.renovatebot.com/modules/manager/gradle/ +archive_url: +related_branches: [feature-build-release-supply-chain-contract] +related_projects: [] +tags: [official-doc, ca-skeleton, ci-cd, gradle, build-tooling] +created: 2026-06-15 +--- + +# Renovate Gradle Manager — Official Documentation + +> Layer: `raw/official-docs/` — 외부 공식 문서의 원문 발췌·출처 기록. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 별도 작성. 원본은 raw에 영구 보관. + +## Parent / 활용 branch (필수, 최소 1개+) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-build-release-supply-chain-contract]] | Decision D3 — "dependency upgrade bot = Renovate 기본"의 근거: Renovate의 Gradle 지원 범위(파일 목록, lockfile 갱신 via --write-locks, Version Catalog 지원), 및 `allowedUnsafeExecutions: ["gradleWrapper"]` supply-chain 보안 제약 | + +## 출처 / Source + +- 원본 URL: https://docs.renovatebot.com/modules/manager/gradle/ +- 아카이브 URL: +- 저자 / 조직: Renovate (Mend) +- 발행일: (연속 갱신 문서 — 발행일 단일 표기 없음) +- 마지막 확인일: 2026-06-15 + +## 왜 저장했는지 / Why archived + +`feature-build-release-supply-chain-contract` branch 의 D3 결정("dependency upgrade bot = Renovate 기본")이 `UNSUPPORTED_DECISION` 으로 분류되어 있었기 때문이다. Renovate 공식 문서에서 Gradle 파일 패턴 매칭 범위, lockfile 갱신 방식(`--write-locks`), Version Catalog(`.versions.toml`) 지원, 그리고 self-hosted 환경에서 `gradleWrapper` 실행의 supply-chain 보안 제약을 직접 확인하여 D3 결정을 근거 있는 선택으로 전환한다. + +## 핵심 인용 / Key quotes (verbatim, 3~5문장) + +> [§File Patterns Matched] "The Gradle manager detects dependencies in files matching these patterns:" +> `/\.gradle(\.kts)?$/` +> `/(^|/)gradle\.properties$/` +> `/(^|/)gradle/.+\.toml$/` +> `/(^|/)buildSrc/.+\.kt$/` +> `/\.versions\.toml$/` +> `/(^|/)versions.props$/` +> `/(^|/)versions.lock$/` + +> [§Lockfile Support] "The manager maintains `gradle.lockfile` artifacts. During maintenance operations, it \"calls `./gradlew :dependencies --write-locks` on the root project and subprojects.\" For standard updates, the tool \"automatically updates lock state entries via the `--update-locks` command line flag.\"" + +> [§Gradle Wrapper Execution] "Renovate will only execute the Gradle Wrapper (via `./gradlew` or `gradlew.bat`) if the self-hosted administrator configures `allowedUnsafeExecutions` to include the `gradleWrapper` option." This requirement exists due to "possible supply chain security attack vectors that can occur with the Gradle Wrapper being executed." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| RENOV-GRAD-C1 | Renovate Gradle manager 는 `.gradle`, `.gradle.kts`, `gradle.properties`, `*.toml`(gradle/ 디렉터리), `.versions.toml`, `versions.props`, `versions.lock` 파일 패턴을 대상으로 의존성을 탐지한다 | [§File Patterns Matched] "The Gradle manager detects dependencies in files matching these patterns: `/\.gradle(\.kts)?$/`, `/(^|/)gradle\.properties$/`, `/(^|/)gradle/.+\.toml$/`, `/\.versions\.toml$/`, `/(^|/)versions.props$/`, `/(^|/)versions.lock$/`" | `official-vendor-doc` | Renovate 사용 모든 Gradle 프로젝트 (self-hosted 포함) | Gradle 외 빌드 시스템(Maven, Bazel)의 파일 패턴; 커스텀 파일 경로 지원 여부 | +| RENOV-GRAD-C2 | Renovate 는 `gradle.lockfile` 유지 시 루트 프로젝트 및 서브프로젝트에 `./gradlew :dependencies --write-locks` 를 실행한다 | [§Lockfile Support] "calls `./gradlew :dependencies --write-locks` on the root project and subprojects" | `official-vendor-doc` | Renovate 로 lockfile maintenance 를 활성화한 Gradle 프로젝트 | `gradleWrapper` 실행 허가(`allowedUnsafeExecutions`) 없이 이 동작이 가능하다는 의미가 아님(C3 참조) | +| RENOV-GRAD-C3 | self-hosted 환경에서 Renovate 가 Gradle Wrapper(`./gradlew`)를 실행하려면 관리자가 `allowedUnsafeExecutions` 에 `gradleWrapper` 옵션을 포함시켜야 한다 | [§Gradle Wrapper Execution] "Renovate will only execute the Gradle Wrapper (via `./gradlew` or `gradlew.bat`) if the self-hosted administrator configures `allowedUnsafeExecutions` to include the `gradleWrapper` option." | `official-vendor-doc` | self-hosted Renovate 인스턴스 운영자 | Renovate Cloud(app.renovatebot.com) 환경 — 관리 방식이 다를 수 있음 | +| RENOV-GRAD-C4 | `gradleWrapper` 실행 허가가 supply-chain 공격 벡터(supply chain security attack vectors)와 관련된 보안 제약이다 | [§Gradle Wrapper Execution] "possible supply chain security attack vectors that can occur with the Gradle Wrapper being executed." | `official-vendor-doc` | self-hosted 환경에서 Renovate PR 자동 머지 + lockfile 재생성을 구성할 때 | Gradle Wrapper 자체의 CVE; Renovate 외 다른 도구의 gradlew 실행 위험 | +| RENOV-GRAD-C5 | Renovate 는 일반 업데이트 시 `--update-locks` CLI 플래그를 통해 lock state 항목을 자동으로 갱신한다 | [§Lockfile Support] "automatically updates lock state entries via the `--update-locks` command line flag" | `official-vendor-doc` | Renovate 로 개별 의존성 버전 업데이트 PR 생성 시 | 전체 lockfile 재생성(`--write-locks`) 과 동일하지 않음 — 개별 항목 업데이트 전용 | + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `RENOV-GRAD-C1`: Renovate 가 Gradle Version Catalog(`.versions.toml`)를 포함한 Gradle 관련 파일 패턴을 공식 지원한다. + - `RENOV-GRAD-C2`: lockfile 유지 모드에서 `--write-locks` 를 실행한다. + - `RENOV-GRAD-C3`: self-hosted 환경에서 `allowedUnsafeExecutions: [gradleWrapper]` 설정이 필수 전제조건이다. + - `RENOV-GRAD-C4`: 이 전제조건이 존재하는 이유가 supply-chain 보안 위협이라는 것을 Renovate 공식 문서가 명시적으로 인정한다. + - `RENOV-GRAD-C5`: 개별 의존성 업데이트 PR 생성 시 `--update-locks` 를 사용한다. +- 이 자료가 증명하지 않는 것: + - Renovate 가 Gradle 외 빌드 시스템(Maven, Bazel)에서 동일하게 동작한다는 것. + - Renovate Cloud(호스팅 서비스) 환경에서 `allowedUnsafeExecutions` 가 동일하게 적용된다는 것. + - Dependabot 대비 Renovate 의 기능 우위 — 이 문서는 Renovate 자체의 기능만 설명하며 비교 없음. + - `gradleWrapper` 실행이 안전하다는 주장 — 오히려 반대. +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - ca-skeleton self-hosted Renovate 인스턴스 구성 시 `allowedUnsafeExecutions: ["gradleWrapper"]` 실제 설정 위치(Renovate config 파일 또는 환경 변수) 확인 필요. + - `gradle/locks/*.lockfile` 패턴(ca-skeleton D8) 과 Renovate 가 기대하는 `gradle.lockfile` 패턴 간 경로 충돌 여부 확인 필요. + +## 메모 / Notes + +- D3 업그레이드: `RENOV-GRAD-C1`~`C3` 로 D3 는 `UNSUPPORTED_DECISION` 에서 `official-vendor-doc` 뒷받침 결정으로 전환 가능. +- D3 의 "Dependabot 은 조직 표준일 때 허용" 부분은 여전히 외부 raw source 미확보 — Dependabot 공식 docs 추가 보강 권고. +- lockfile 경로 불일치 주의: D8 의 `gradle/locks/*.lockfile` vs Renovate 문서의 `gradle.lockfile` — 경로가 다를 경우 Renovate 가 lockfile 을 탐지하지 못할 수 있음. `/(^|/)versions.lock$/` 패턴과의 관계 확인 필요. +- 추가로 봐야 할 동일 출처 페이지: `https://docs.renovatebot.com/self-hosted-configuration/#allowedunsafeexecutions` (self-hosted config 레퍼런스) + +## Related / 관련 + +- 같은 주제 다른 official-doc: [[raw/official-docs/supply-chain-gradle-vs-maven-dependency-locking]] (D8 근거 — Gradle dependency-locking) +- 이 자료를 인용한 wiki 요약: (생성 시 추가) diff --git a/vault/20-evidence/official-docs/renovate-vulnerability-alerts-gradle-official.md b/vault/20-evidence/official-docs/renovate-vulnerability-alerts-gradle-official.md new file mode 100644 index 0000000..f580d80 --- /dev/null +++ b/vault/20-evidence/official-docs/renovate-vulnerability-alerts-gradle-official.md @@ -0,0 +1,106 @@ +--- +title: Renovate Security Presets — security:only-security-updates (Official Docs) +source_type: official-doc +url: https://docs.renovatebot.com/presets-security/ +archive_url: +related_branches: [feature-dependency-vulnerability-management-contract] +related_projects: [] +tags: [official-doc, ci-cd, gradle, security] +created: 2026-06-15 +--- + +# Renovate Security Presets — security:only-security-updates (Official Docs) + +> Layer: `raw/` — 외부 자료(공식 문서)의 **원문 발췌·출처 기록**. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 `source-summary-template` 형식으로 별도 작성. 원본은 raw에 영구 보관. + +## Parent / 활용 branch (필수, 최소 1개+) + +> 이 자료는 **혼자 존재하지 않는다.** 어느 branch(또는 project)의 구현 결정의 **근거**로서 보관됨. + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-dependency-vulnerability-management-contract]] | Renovate를 primary security-update 자동 PR 도구로 채택. `security:only-security-updates` preset이 `osvVulnerabilityAlerts: true` + `vulnerabilityAlerts.enabled: true`를 켜고, 전체 패키지 업데이트를 비활성화한 뒤 취약점 감지 시에만 PR을 생성한다는 것이 근거. | + +## 출처 / Source + +- 원본 URL: https://docs.renovatebot.com/presets-security/ +- 아카이브 URL: (미등록) +- 저자 / 조직: Renovate (Mend) +- 발행일: (continuous — 마지막 확인: 2026-06-15) +- 마지막 확인일: 2026-06-15 +- 문서 버전 footer: "These docs correspond to Mend Renovate version 43.222.1" + +## 왜 저장했는지 / Why archived + +`feature-dependency-vulnerability-management-contract` 에서 Renovate를 security-update 자동 PR 도구로 채택하는 결정을 정당화하기 위해 보관. `security:only-security-updates` preset의 동작(취약점 감지 시에만 PR, `osvVulnerabilityAlerts: true`)을 공식 문서에서 verbatim으로 확인. + +## 핵심 인용 / Key quotes (verbatim, 3~5문장) + +> [§security:only-security-updates] "Only update dependencies if vulnerabilities have been detected." + +> [§security:only-security-updates / JSON config] `"osvVulnerabilityAlerts": true,` + +> [§security:only-security-updates / JSON config] Full preset configuration: +> ```json +> { +> "extends": [ +> "config:recommended" +> ], +> "osvVulnerabilityAlerts": true, +> "packageRules": [ +> { +> "enabled": false, +> "matchPackageNames": [ +> "*" +> ] +> } +> ], +> "vulnerabilityAlerts": { +> "enabled": true +> } +> } +> ``` + +> [§security:minimumReleaseAgeNpm] "Wait until the npm package is three days old before raising the update. This a) introduces a short delay to allow for malware researchers and scanners to (possibly) detect any malicious behaviour in packages, and b) prevents the maintainer and/or NPM from unpublishing a package you already upgraded to, breaking builds." + +> [§security:openssf-scorecard] "Show OpenSSF badge on pull requests." + +## Claims Extracted / 추출된 주장 + +> 이 자료가 **직접 말하는 것만** claim 으로 분리한다. 내 프로젝트에 적용한 결론은 여기 쓰지 않는다. + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| C1 | `security:only-security-updates` preset은 취약점이 감지된 경우에만 의존성을 업데이트한다. | [§security:only-security-updates] "Only update dependencies if vulnerabilities have been detected." | `official-vendor-doc` | Renovate를 사용하는 모든 프로젝트에서 이 preset을 extends 또는 직접 적용할 때 | 이 preset이 특정 런타임/생태계에서 완전히 동작함을 보장하지 않음. Gradle lockfile 지원 여부는 별도 확인 필요 | +| C2 | `security:only-security-updates` preset은 `config:recommended`를 상속하고, `osvVulnerabilityAlerts: true`와 `vulnerabilityAlerts: {enabled: true}`를 설정하며, 기본적으로 모든 패키지 업데이트를 비활성화(`enabled: false, matchPackageNames: ["*"]`)한다. | [§security:only-security-updates / JSON config] `"osvVulnerabilityAlerts": true,` + `"vulnerabilityAlerts": {"enabled": true}` + `"enabled": false, "matchPackageNames": ["*"]` | `official-vendor-doc` | Renovate를 사용하는 모든 프로젝트 | `osvVulnerabilityAlerts` 또는 `vulnerabilityAlerts`의 상세 동작(schedule 무시 여부, PR 생성 조건 등)은 이 preset 페이지에서 직접 설명되지 않음. 별도 configuration-options 페이지 확인 필요 | +| C3 | `security:only-security-updates`는 `config:recommended`를 extends한다. | [§security:only-security-updates / JSON config] `"extends": ["config:recommended"]` | `official-vendor-doc` | 이 preset을 renovate.json에 추가할 때 | `config:recommended`의 구체적 내용은 이 페이지에서 설명되지 않음 | +| C4 | Renovate는 security 관련 preset으로 `security:minimumReleaseAgeNpm`, `security:only-security-updates`, `security:openssf-scorecard` 3개를 제공한다. | [§Security Presets] 세 개 preset 섹션 모두 존재 | `official-vendor-doc` | Renovate security presets 카탈로그 파악 | 이 세 preset 외에 다른 security preset이 없다는 보장은 아님 (문서 버전 43.222.1 기준) | + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `C1`: `security:only-security-updates` preset의 의도(취약점 감지 시에만 업데이트) + - `C2`: preset의 정확한 JSON 구성 — `osvVulnerabilityAlerts`, `vulnerabilityAlerts.enabled`, packageRules 비활성화 + - `C3`: `config:recommended` 상속 관계 + - `C4`: Renovate 공식 security preset 카탈로그 (v43.222.1 기준) +- 이 자료가 증명하지 않는 것: + - `vulnerabilityAlerts`가 schedule을 무시하는지 여부 (configuration-options 페이지 별도 확인 필요) + - `osvVulnerabilityAlerts`의 experimental 상태 여부 (configuration-options 페이지 별도 확인 필요) + - Gradle lockfile 또는 Gradle-specific 의존성에서 이 preset이 동작하는지 + - PR merge 조건 및 automerge 동작 +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - ca-tmpl 의 `renovate.json`에 이 preset 적용 후 Gradle lockfile 취약점 탐지가 실제로 동작하는지 로컬 검증 필요 + - `osvVulnerabilityAlerts` datasource 지원 범위 (Maven / Gradle 포함 여부) — configuration-options 페이지 확인 + +## 메모 / Notes + +- 이 페이지는 preset의 JSON 구성을 보여주지만 `vulnerabilityAlerts`와 `osvVulnerabilityAlerts`의 상세 동작(schedule 무시, PR 생성 조건 등)은 https://docs.renovatebot.com/configuration-options/ 에서 설명됨 — 해당 페이지도 별도 raw source로 등록 권고. +- 문서 버전 footer: "These docs correspond to Mend Renovate version 43.222.1" — 버전별 동작 차이 가능성 있음. +- `osvVulnerabilityAlerts`의 experimental 상태 여부는 이 페이지에서 확인 불가. configuration-options 페이지 fetch 필요. + +## Related / 관련 + +- 같은 주제 다른 official-doc: [[raw/official-docs/dependabot-security-updates-gradle-official]] +- 이 자료를 인용한 wiki 요약: `[[wiki/concepts/<...>]]` (생성 시) +- 추가 fetch 필요: https://docs.renovatebot.com/configuration-options/#vulnerabilityalerts, https://docs.renovatebot.com/configuration-options/#osvvulnerabilityalerts diff --git a/vault/20-evidence/official-docs/reproducible-builds-org-jvm-guide.md b/vault/20-evidence/official-docs/reproducible-builds-org-jvm-guide.md new file mode 100644 index 0000000..7fdf1d6 --- /dev/null +++ b/vault/20-evidence/official-docs/reproducible-builds-org-jvm-guide.md @@ -0,0 +1,93 @@ +--- +title: official-doc / Reproducible Builds — JVM Guide (reproducible-builds.org) +source_type: official-doc +url: https://reproducible-builds.org/docs/jvm/ +archive_url: +related_branches: [feature-build-release-supply-chain-contract] +related_projects: [ca-skeleton] +tags: [official-doc, ca-skeleton, ci-cd, gradle, reproducible-builds, supply-chain] +created: 2026-06-15 +vendor: reproducible-builds.org +--- + +# official-doc / Reproducible Builds — JVM Guide (reproducible-builds.org) + +> Layer: `raw/` — 외부 자료(공식 문서)의 원문 발췌·출처 기록. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 `source-summary-template` 형식으로 별도 작성. 원본은 raw에 영구 보관. + +## Parent / 활용 branch + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-build-release-supply-chain-contract]] | Decision D10 — reproducible builds 의 cross-ecosystem 정의 + JVM nondeterminism 원인(timestamps, file ordering, locale, umask)이 Gradle 두 설정(`preserveFileTimestamps=false`, `reproducibleFileOrder=true`)으로 일부 해결됨을 공식 근거로 뒷받침 | + +## 출처 / Source + +- 원본 URL: https://reproducible-builds.org/docs/jvm/ +- 아카이브 URL: (미등록) +- 저자 / 조직: reproducible-builds.org (community initiative) +- 발행일: 미표기 (지속 갱신) +- 마지막 확인일: 2026-06-15 + +보조 정의 출처: https://reproducible-builds.org/docs/definition/ + +## 왜 저장했는지 / Why archived + +branch-note `feature-build-release-supply-chain-contract` 의 D10(`build reproducibility = preserveFileTimestamps=false, reproducibleFileOrder=true, JDK pin`)이 `UNSUPPORTED_DECISION` 라벨을 갖고 있었고, 공식 외부 source 등록이 권고된 상태였다. 본 문서는 재현가능 빌드의 공식 정의와 JVM 비결정성 원인 목록(timestamps, file ordering, locale, umask) 및 Gradle 설정 방법을 원문으로 제공하여 D10 결정을 `official-reference` 강도로 뒷받침한다. + +## 핵심 인용 / Key quotes (verbatim, 5문장) + +> [§definition] "A build is reproducible if given the same source code, build environment and build instructions, any party can recreate bit-by-bit identical copies of all specified artifacts." + +> [§JVM intro] "The `javac` compiler generates reproducible bytecode `.class` output as do most language-specific compilers, but JVM packaging (in `.jar` files) is not reproducible-friendly – particularly timestamp of files in the archive –, each build tool requires some work mostly at packaging step to provide Reproducible Builds." + +> [§Gradle] "Tasks which generate archives, such as ZIPs, JARs or Tarballs, can enforce preserved file timestamps and reproducible file order which fix two of the main sources of non-determinism in JVM artifacts. Consider setting `dirPermissions` and `filePermissions` to adjust environment specific `umask` settings." + +> [§Properties files] "All properties files generated using `java.util.Properties.store()` contain a comment line with the generation timestamp. The Java system property `java.properties.date` can be used to set a fixed value used instead of the generation timestamp." + +> [§Character set + locales] "When building with Java 17 or older, consider setting `file.encoding=UTF-8`. UTF-8 is the default since Java 18. Other system properties to consider depending on your build requirements are `user.language`, `user.country`, `user.variant`." + +## Claims Extracted / 추출된 주장 + +> 이 자료가 **직접 말하는 것만** claim 으로 분리한다. + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| RB-JVM-C1 | Reproducible build 의 공식 정의: 동일 소스코드 + 빌드환경 + 빌드지침이 주어지면 누구든 모든 지정 아티팩트를 비트 단위로 동일하게 재현할 수 있어야 함 | [§definition] "A build is reproducible if given the same source code, build environment and build instructions, any party can recreate bit-by-bit identical copies of all specified artifacts." | `official-reference` | reproducible-builds.org 가 cross-ecosystem 정의로 채택한 기준 | 이 정의가 특정 도구(Gradle 등)에서 자동 달성됨을 의미하지 않음; 달성 여부는 설정과 환경에 따라 다름 | +| RB-JVM-C2 | JVM 아티팩트 패키징(`.jar`)은 기본적으로 재현가능하지 않음 — 주요 원인은 아카이브 내 파일 타임스탬프 | [§JVM intro] "JVM packaging (in `.jar` files) is not reproducible-friendly – particularly timestamp of files in the archive –, each build tool requires some work mostly at packaging step to provide Reproducible Builds." | `official-reference` | Gradle/Maven/sbt 로 `.jar` 를 생성하는 모든 JVM 프로젝트 | Java `.class` 바이트코드 자체는 재현가능(`javac`); 비재현성은 패키징(아카이브 생성) 단계에서 발생함을 한정 | +| RB-JVM-C3 | Gradle 의 `isPreserveFileTimestamps=false` + `isReproducibleFileOrder=true` 두 설정이 JVM 아티팩트의 두 가지 주요 비결정성 원인을 제거함 | [§Gradle] "Tasks which generate archives, such as ZIPs, JARs or Tarballs, can enforce preserved file timestamps and reproducible file order which fix two of the main sources of non-determinism in JVM artifacts." | `official-reference` | Gradle v3.4 이상, `AbstractArchiveTask` 를 상속하는 모든 아카이브 태스크 (Jar, Zip, Tar) | `dirPermissions`/`filePermissions` 을 별도 설정하지 않으면 umask 차이로 인한 비결정성이 잔존함; 또한 locale/encoding 비결정성은 별도 설정 필요 | +| RB-JVM-C4 | Gradle 에서 `dirPermissions`, `filePermissions` 설정으로 umask 기인 비결정성을 추가로 제거 가능 | [§Gradle] "Consider setting `dirPermissions` and `filePermissions` to adjust environment specific `umask` settings." | `official-reference` | Gradle 로 아카이브를 생성하는 환경이 다른 CI/로컬 빌더 간 umask 가 다를 때 | umask 통일만으로 전체 재현가능성이 보장되지 않음 (locale/타임스탬프도 별도 처리 필요) | +| RB-JVM-C5 | `java.util.Properties.store()` 로 생성되는 `.properties` 파일에는 생성 타임스탬프 주석이 포함되며, `java.properties.date` 시스템 프로퍼티로 고정값으로 대체 가능 | [§Properties files] "All properties files generated using `java.util.Properties.store()` contain a comment line with the generation timestamp. The Java system property `java.properties.date` can be used to set a fixed value used instead of the generation timestamp." | `official-reference` | `java.util.Properties.store()` 를 직접 호출하거나 간접 호출하는 라이브러리(예: Spring `application.properties` 등)를 사용하는 모든 JVM 빌드 | Spring Boot 같은 프레임워크가 이 메서드를 호출하지 않으면 영향 없음; 주석 제거 여부는 도구 버전에 따라 다를 수 있음 | +| RB-JVM-C6 | Java 17 이하에서 `file.encoding=UTF-8` 설정 권고 (Java 18+ 기본값); `user.language`, `user.country`, `user.variant` 도 빌드 요건에 따라 고정 권고 | [§Character set + locales] "When building with Java 17 or older, consider setting `file.encoding=UTF-8`. UTF-8 is the default since Java 18. Other system properties to consider depending on your build requirements are `user.language`, `user.country`, `user.variant`." | `official-reference` | Java 17 이하 JVM 환경의 다국어 빌드, 또는 locale 에 따라 출력이 달라지는 플러그인/라이브러리 사용 시 | Java 18+ 에서는 `file.encoding` 기본값이 UTF-8 이므로 해당 설정 불필요; `user.language` 등의 고정 필요성은 빌드 내용에 따라 다름 | + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `RB-JVM-C1`: reproducible-builds.org 의 교차-에코시스템 공식 정의 (bit-for-bit 동일 복제 가능) + - `RB-JVM-C2`: JVM `.jar` 패키징이 기본 비재현적임 (원인: 아카이브 타임스탬프) + - `RB-JVM-C3`: Gradle `isPreserveFileTimestamps=false` + `isReproducibleFileOrder=true` 가 두 가지 주요 비결정성 원인을 제거함 (Gradle v3.4+) + - `RB-JVM-C4`: `dirPermissions`/`filePermissions` 설정으로 umask 기인 비결정성 추가 제거 가능 + - `RB-JVM-C5`: Properties 타임스탬프 문제 + `java.properties.date` 로 고정 가능 + - `RB-JVM-C6`: `file.encoding=UTF-8` + `user.language`/`user.country`/`user.variant` locale 고정 권고 +- 이 자료가 증명하지 않는 것: + - 위 설정들만 적용하면 100% 재현가능 빌드가 보장된다는 주장 (잔존 비결정성 원인 가능) + - JDK 버전 고정(`tool-versions`)이 재현가능성에 기여함 (본 문서에 JDK 버전 고정 명시 없음 — 별도 근거 필요) + - Maven, sbt 의 재현가능 설정 방법론 (본 문서는 overview 수준만 제공, 상세는 각 도구 공식 문서 필요) + - Gradle 설정 적용 후 실제로 두 환경에서 동일 hash 가 나온다는 검증 (별도 실험으로 확인 필요) +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - ca-tmpl 에서 Gradle `AbstractArchiveTask` 설정 실제 적용 후 동일 commit 2회 빌드 → SHA-256 비교 (`needs-confirmation`) + - Spring Boot 의 `bootJar` task 가 `AbstractArchiveTask` 를 상속하므로 동일 설정 적용 가능한지 확인 + - `java.properties.date` 시스템 프로퍼티가 Gradle 빌드 스크립트에서 어떻게 전달되는지 확인 + +## 메모 / Notes + +- 인용 `RB-JVM-C3` 는 "two of the main sources" 라고 표현 — '주요 두 원인 *중 하나*를 제거한다'는 뜻이 아니라 '타임스탬프와 파일 순서라는 두 원인을 제거한다'는 뜻. "of the main" 이 축소 표현이 아님. +- branch-note D10 은 `JDK version pin via .tool-versions` 도 기술하는데, 본 문서(reproducible-builds.org)에는 JDK 버전 고정에 대한 직접 진술이 없음 — JDK 고정 근거는 별도 Gradle Wrapper 또는 Toolchain 공식 문서 source 필요. +- Gradle example 코드블록은 Kotlin DSL 기준 (`isPreserveFileTimestamps`, `isReproducibleFileOrder` — Groovy DSL 에서는 `preserveFileTimestamps`, `reproducibleFileOrder` 로 표현됨). ca-tmpl 이 어느 DSL 쓰는지 확인 후 적용. +- 추가로 봐야 할 동일 출처 페이지: `https://reproducible-builds.org/docs/` (index), Maven guide to configuring reproducible builds. + +## Related / 관련 + +- 본 자료를 인용한 branch-note: [[raw/branch-notes/feature-build-release-supply-chain-contract]] +- 같은 주제 다른 official-doc: [[raw/official-docs/supply-chain-slsa-provenance-framework]], [[raw/official-docs/supply-chain-cosign-keyless-sigstore]] +- 이 자료를 인용한 wiki 요약: (생성 시 추가) diff --git a/vault/20-evidence/official-docs/resilience4j-micrometer-module.md b/vault/20-evidence/official-docs/resilience4j-micrometer-module.md new file mode 100644 index 0000000..b5f6114 --- /dev/null +++ b/vault/20-evidence/official-docs/resilience4j-micrometer-module.md @@ -0,0 +1,110 @@ +--- +title: Resilience4j — Micrometer Module (Tagged Metrics for CircuitBreaker / Retry / Bulkhead / RateLimiter) +source_type: official-doc +url: https://resilience4j.readme.io/docs/micrometer +archive_url: +related_projects: [] +related_branches: [feature-outbound-http-client-baseline, feature-metrics-alerting-contract] +tags: [resilience4j, micrometer, metrics, circuit-breaker, retry, bulkhead, rate-limiter, thread-pool-bulkhead, prometheus, observability, official-doc] +status: raw +confidence: high +created: 2026-05-27 +last_reviewed: 2026-05-27 +--- + +# Resilience4j — Micrometer Module (Tagged Metrics for CircuitBreaker / Retry / Bulkhead / RateLimiter) + +> Layer: `raw/official-docs/` — Resilience4j 공식 docs "Micrometer" 페이지 verbatim. +> outbound HTTP client 의 CircuitBreaker/Retry/Bulkhead 가 Prometheus 로 노출되는 metric 이름·tag·state 의 1차 근거. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-outbound-http-client-baseline]] | D4 — 외부 호출에 Resilience4j CircuitBreaker + Retry 적용 시 metric 이 자동 노출되는 mechanism 의 공식 근거 (`resilience4j.circuitbreaker.calls`, `kind`/`name` tag 등) | +| [[raw/branch-notes/feature-metrics-alerting-contract]] | Prometheus alerting rule 의 base metric (calls/state/concurrent.calls/queue.depth/available.permissions) 명명 규약 | + +## 컨텍스트 + +ca-tmpl 계열 프로젝트의 outbound HTTP client (RestClient + Resilience4j) 는 호출 결과를 Prometheus 로 노출해 SLO/alerting 의 기반으로 삼는다. 본 자료는 Resilience4j 의 Micrometer 모듈이 자동 생성하는 metric 의 정확한 이름·tag·state vocabulary 를 verbatim 으로 보존하기 위한 raw. circuitbreaker.state 의 5개 state ("closed", "open", "half_open", "forced_open", "disabled") 와 calls 의 kind tag ("successful", "failed", "ignored") 가 alerting rule 의 label matcher 기준. + +## 출처 / Source + +- 원본 URL: https://resilience4j.readme.io/docs/micrometer +- 아카이브 URL: (미수집) +- 저자 / 조직: Resilience4j project (community-maintained, official module 문서) +- 발행일: rolling docs (current = 2.x) +- 마지막 확인일: 2026-05-27 + +## 왜 저장했는지 / Why archived + +Outbound HTTP client baseline 결정에서 "관측 가능성은 Resilience4j Micrometer 모듈을 그대로 사용한다" 는 선택의 근거. Prometheus query / Grafana panel / alerting rule 모두 본 페이지의 metric 명명을 그대로 쓰기 때문에 verbatim 보존 필요. + +## 핵심 인용 / Key quotes (verbatim) + +> [§Micrometer] "Resilience4j provides a module for Micrometer which supports most popular monitoring systems like InfluxDB or Prometheus." + +> [§CircuitBreaker Metrics] "The following code snippet shows how to bind CircuitBreaker metrics to a MeterRegistry." + +> [§CircuitBreaker Metrics] "resilience4j.circuitbreaker.calls" with tags: "kind=\"failed\" kind=\"successful\" kind=\"ignored\"" and "name=\"backendA\"" + +> [§CircuitBreaker Metrics] "resilience4j.circuitbreaker.state" is a Gauge with states: "closed" "open" "half_open" "forced_open" "disabled" + +> [§Retry Metrics] "TaggedRetryMetrics.ofRetryRegistry(retryRegistry).bindTo(meterRegistry);" + +> [§Bulkhead Metrics] "resilience4j.bulkhead.available.concurrent.calls" - "The number of available permissions" + +> [§ThreadPoolBulkhead Metrics] "resilience4j.bulkhead.queue.depth" measures "The queue depth. The number of tasks waiting to be executed" + +> [§RateLimiter Metrics] "resilience4j.ratelimiter.available.permissions" and "resilience4j.ratelimiter.waiting.threads" + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| R4J-MICROMETER-C1 | Resilience4j 는 Micrometer 모듈을 제공하며 이는 InfluxDB, Prometheus 등 주요 monitoring system 으로의 노출을 지원한다 | [§Micrometer] "Resilience4j provides a module for Micrometer which supports most popular monitoring systems like InfluxDB or Prometheus." | `official-vendor-doc` | Resilience4j 2.x + Micrometer 1.x | 특정 monitoring system 의 정확한 scrape 설정/dashboard 는 본 인용 범위 밖 | +| R4J-MICROMETER-C2 | CircuitBreaker metric 은 `MeterRegistry` 에 bind 해서 노출하며, 호출 결과는 `resilience4j.circuitbreaker.calls` 라는 metric 으로 노출되고 `kind` (successful/failed/ignored) 와 `name` (instance 명) tag 가 붙는다 | [§CircuitBreaker Metrics] "The following code snippet shows how to bind CircuitBreaker metrics to a MeterRegistry." + "resilience4j.circuitbreaker.calls" with tags: "kind=\"failed\" kind=\"successful\" kind=\"ignored\"" and "name=\"backendA\"" | `official-vendor-doc` | Tagged*Metrics binder 또는 spring-boot-starter auto-config 사용 시 | Spring Boot starter 가 자동으로 bind 한다는 뜻은 본 인용에서는 명시 안 됨 — starter 별 페이지 참조 필요 | +| R4J-MICROMETER-C3 | CircuitBreaker state 는 `resilience4j.circuitbreaker.state` 라는 Gauge 로 노출되며 가능한 state 는 5개: `closed`, `open`, `half_open`, `forced_open`, `disabled` | [§CircuitBreaker Metrics] "resilience4j.circuitbreaker.state" is a Gauge with states: "closed" "open" "half_open" "forced_open" "disabled" | `official-vendor-doc` | Resilience4j CircuitBreaker | state transition latency / failure rate threshold 등 다른 metric 은 별도 인용 필요 | +| R4J-MICROMETER-C4 | Retry metric 은 `TaggedRetryMetrics.ofRetryRegistry(retryRegistry).bindTo(meterRegistry)` 패턴으로 등록한다 | [§Retry Metrics] "TaggedRetryMetrics.ofRetryRegistry(retryRegistry).bindTo(meterRegistry);" | `official-vendor-doc` | Resilience4j Retry + Micrometer 수동 binder | spring-boot-starter 사용 시 자동 bind 여부는 본 인용 범위 밖 | +| R4J-MICROMETER-C5 | Bulkhead 는 `resilience4j.bulkhead.available.concurrent.calls` metric 으로 남은 permission 수를 노출한다 | [§Bulkhead Metrics] "resilience4j.bulkhead.available.concurrent.calls" - "The number of available permissions" | `official-vendor-doc` | Semaphore 기반 Bulkhead | ThreadPoolBulkhead 의 metric 명은 다름 (별도 C6 참조) | +| R4J-MICROMETER-C6 | ThreadPoolBulkhead 의 큐 깊이는 `resilience4j.bulkhead.queue.depth` metric 으로 노출되며 "큐에서 실행 대기 중인 task 수" 를 의미한다 | [§ThreadPoolBulkhead Metrics] "resilience4j.bulkhead.queue.depth" measures "The queue depth. The number of tasks waiting to be executed" | `official-vendor-doc` | ThreadPoolBulkhead | core thread pool size / max thread pool size 의 metric 명은 본 인용 범위 밖 | +| R4J-MICROMETER-C7 | RateLimiter 는 `resilience4j.ratelimiter.available.permissions` (남은 permission) 과 `resilience4j.ratelimiter.waiting.threads` (대기 thread 수) 두 metric 을 노출한다 | [§RateLimiter Metrics] "resilience4j.ratelimiter.available.permissions" and "resilience4j.ratelimiter.waiting.threads" | `official-vendor-doc` | Resilience4j RateLimiter | refresh period / limit-for-period 의 metric 노출 여부는 본 인용 범위 밖 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `R4J-MICROMETER-C1`: Micrometer 모듈의 Prometheus/InfluxDB 지원 사실 + - `R4J-MICROMETER-C2`: CircuitBreaker calls metric 명 + kind/name tag vocabulary + - `R4J-MICROMETER-C3`: CircuitBreaker state 의 5개 정확한 state 이름 + - `R4J-MICROMETER-C4`: Retry metric binder API 정확한 호출 형태 + - `R4J-MICROMETER-C5`: Bulkhead 의 available concurrent calls metric 명 + - `R4J-MICROMETER-C6`: ThreadPoolBulkhead 의 queue depth metric 명 + 의미 + - `R4J-MICROMETER-C7`: RateLimiter 의 두 핵심 metric 명 +- **이 자료가 증명하지 않는 것**: + - Spring Boot starter (`resilience4j-spring-boot3`) 가 자동으로 모든 metric 을 bind 한다는 뜻 — auto-config 동작은 별도 starter 문서 필요 + - Histogram / percentile (p50/p95/p99) 가 default 로 노출된다는 뜻 — Micrometer side 의 `meterFilter` / distributionStatistic 설정 필요할 수 있음 + - Prometheus 의 scrape 주기, retention, alerting rule 의 정확한 형태 + - CircuitBreaker `state` Gauge 의 정확한 라벨 인코딩 (state 별 별도 series 인지 단일 series 의 value 인지) +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 의 `resilience4j-spring-boot3` 의존성이 위 metric 들을 `/actuator/prometheus` 에 자동 노출하는지 (`management.endpoints.web.exposure.include=prometheus`) + - `resilience4j.circuitbreaker.state{state="open"} == 1` 형태의 PromQL 가 작동하는지 (state 인코딩 검증) + - alerting rule 작성 시 `kind="failed"` label matcher 가 정확히 매치되는지 + +## 메모 / Notes + +- 인용 1 해석 후보 (미검증): + - state Gauge 의 value 가 boolean(0/1) 인지 enum index 인지는 본 인용에서 미명시 → 실측 필요 +- 추가로 봐야 할 동일 출처 페이지: + - https://resilience4j.readme.io/docs/getting-started-3 (Spring Boot starter auto-config) + - https://resilience4j.readme.io/docs/circuitbreaker (CircuitBreaker 동작 원리) + +## Related / 관련 + +- 같은 주제 다른 official-doc: + - [[raw/official-docs/spring-restclient-builder-reference]] (outbound client 의 baseline) +- 인용하는 branch: + - [[raw/branch-notes/feature-outbound-http-client-baseline]] + - [[raw/branch-notes/feature-metrics-alerting-contract]] +- 인용하는 project: + - [[raw/project-notes/ca-skeleton-operational-contract]] +- 인용하는 wiki: (미작성) diff --git a/vault/20-evidence/official-docs/retry-aws-well-architected-rel05-bp03.md b/vault/20-evidence/official-docs/retry-aws-well-architected-rel05-bp03.md new file mode 100644 index 0000000..539c125 --- /dev/null +++ b/vault/20-evidence/official-docs/retry-aws-well-architected-rel05-bp03.md @@ -0,0 +1,85 @@ +--- +title: "AWS Well-Architected Framework — REL05-BP03: Control and limit retry calls" +source_type: official-doc +url: https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_mitigate_interaction_failure_limit_retries.html +archive_url: +related_branches: [feature-background-job-async-contract] +related_projects: [ca-skeleton] +tags: [official-doc, ca-skeleton, error-handling, aws, exponential-backoff, jitter, retry-policy, dead-letter-queue] +created: 2026-06-11 +--- + +# AWS Well-Architected Framework — REL05-BP03: Control and limit retry calls + +> Layer: `raw/official-docs/` — AWS Well-Architected Framework Reliability Pillar 공식 문서 원문 발췌·출처 기록. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 별도 작성. 원본은 raw에 영구 보관. + +## Parent / 활용 branch + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-background-job-async-contract]] | D4 — "limit the maximum number of retries" 공식 근거 + non-transient error 는 retry 없이 즉시 fail(DLQ) 조건 + anti-pattern (non-idempotent retry / multi-layer retry storm) | + +## 출처 / Source + +- 원본 URL: https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_mitigate_interaction_failure_limit_retries.html +- 아카이브 URL: (미등록) +- 저자 / 조직: Amazon Web Services (AWS Well-Architected Team) +- 발행일: (공식 문서 — 지속 관리 페이지, 특정 발행일 없음) +- 마지막 확인일: 2026-06-11 + +## 왜 저장했는지 / Why archived + +`feature-background-job-async-contract` branch 의 D4 결정(기본 backoff = exponential + jitter, max attempts 제한, DLQ after exhausted)이 `UNSUPPORTED_DECISION` 상태였다. 본 AWS Well-Architected REL05-BP03 공식 문서가 "limit the maximum number of retries", non-transient error retry 금지, multi-layer retry storm anti-pattern 을 직접 권고하므로 D4 의 정량 방향성과 금지 조건의 외부 근거로 보관한다. + +## 핵심 인용 / Key quotes (verbatim) + +> [§Opening summary] "Use exponential backoff to retry requests at progressively longer intervals between each retry. Introduce jitter between retries to randomize retry intervals. Limit the maximum number of retries." + +> [§Benefits] "Finally, it's important to configure a maximum number of retries or elapsed time to avoid creating backlogs that produce metastable failures." + +> [§Common anti-patterns] "Failing to understand published error codes from dependencies, leading to retrying all errors, including those with a clear cause that indicates lack of permission, configuration error, or another condition that predictably will not resolve without manual intervention." + +> [§Common anti-patterns] "Retrying at multiple layers of your application stack in a manner which compounds retry attempts further consuming resources in a retry storm. Be sure to understand how these errors affect your application the dependencies you rely on, then implement retries at only one level." + +> [§Common anti-patterns] "Retrying service calls that are not idempotent, causing unexpected side effects like duplicated results." + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| WAF-REL05-C1 | Retry 는 exponential backoff + jitter + maximum retry 제한 을 반드시 함께 구현해야 한다 | [§Opening] "Use exponential backoff to retry requests at progressively longer intervals between each retry. Introduce jitter between retries to randomize retry intervals. Limit the maximum number of retries." | `official-vendor-doc` | 분산 시스템의 모든 클라이언트 retry 구현 | 최대 retry 횟수의 정확한 정량값(예: 3회)을 직접 지정하지 않음 | +| WAF-REL05-C2 | Maximum retry 횟수 또는 elapsed time 을 설정하지 않으면 backlog 가 누적되어 metastable failure 를 유발한다 | [§Benefits] "it's important to configure a maximum number of retries or elapsed time to avoid creating backlogs that produce metastable failures." | `official-vendor-doc` | retry 있는 모든 클라이언트 코드 | 특정 숫자(3, 5 등) 또는 특정 elapsed time 값을 권고하지 않음 | +| WAF-REL05-C3 | Manual intervention 이 필요한 non-transient error(permission 오류, configuration 오류 등)는 retry 해서는 안 된다 | [§Common anti-patterns] "another condition that predictably will not resolve without manual intervention." | `official-vendor-doc` | 모든 retry 구현의 error 분류 로직 | 어떤 HTTP status code 를 non-transient 로 분류할지 직접 목록화하지 않음 | +| WAF-REL05-C4 | Application stack 의 여러 레이어에서 중첩 retry 는 retry storm 을 유발하며 단일 레이어에서만 구현해야 한다 | [§Common anti-patterns] "Retrying at multiple layers of your application stack in a manner which compounds retry attempts further consuming resources in a retry storm. Be sure to understand how these errors affect your application the dependencies you rely on, then implement retries at only one level." | `official-vendor-doc` | multi-tier 아키텍처 (예: HTTP client + scheduler + outbox publisher 가 모두 retry 하는 경우) | 단일 레이어 위치(service layer vs infrastructure layer)의 선택 기준을 명시하지 않음 | +| WAF-REL05-C5 | Idempotent 하지 않은 서비스 호출에 retry 를 적용하면 중복 결과 등 예상치 못한 부작용이 발생한다 | [§Common anti-patterns] "Retrying service calls that are not idempotent, causing unexpected side effects like duplicated results." | `official-vendor-doc` | retry 구현 전 idempotency 검증이 필요한 모든 서비스 호출 | idempotency 구현 방법(idempotency key, conditional write 등)을 직접 설명하지 않음 (REL04-BP04 참조) | + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `WAF-REL05-C1`: exponential backoff + jitter + max retry limit 의 세 요소가 함께 필요함 + - `WAF-REL05-C2`: max retry 또는 elapsed time 설정 없음 = metastable failure 위험 (Risk: High) + - `WAF-REL05-C3`: non-transient error(manual intervention 필요) → retry 금지 + - `WAF-REL05-C4`: multi-layer retry 중첩 = retry storm anti-pattern → 단일 레이어 구현 + - `WAF-REL05-C5`: non-idempotent 호출에 retry = 중복 부작용 anti-pattern +- 이 자료가 증명하지 않는 것: + - max retry 정확한 정량값(3회, 5회 등). 정량값은 use-case 별 측정 필요 (`WAF-REL05-C1`, `WAF-REL05-C2` 공통) + - DLQ(Dead Letter Queue) 아키텍처 자체의 설계 방법 — DLQ 를 "retry 소진 후 격리"로 사용하는 것은 이 문서의 scope 밖 + - 어떤 HTTP status code 가 "predictably will not resolve" 에 해당하는지 목록화되지 않음 (`WAF-REL05-C3`) + - retry 위치(service layer vs infrastructure layer 중 어디)를 명시하지 않음 (`WAF-REL05-C4`) +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - ca-tmpl background job 의 max=3 결정은 이 문서로 "max limit 필요" 방향을 정당화할 수 있으나 "3이 옳다"는 별도 측정 필요 (`WAF-REL05-C2`) + - outbox publisher + background job executor 가 각각 retry 하는 경우 `WAF-REL05-C4` 위반 여부 검토 — 단일 retry 레이어 지정 필요 + +## 메모 / Notes + +- Risk level = **High** (원문 명시): "Level of risk exposed if this best practice is not established: High" +- AWS Builder's Library 의 "Timeouts, retries, and backoff with jitter" 가 이 문서와 연계됨 — 더 상세한 구현 guidance 포함. 후속 raw 추가 권고. +- REL05-BP04 (Fail fast and limit queues) 및 REL04-BP04 (Make mutating operations idempotent) 가 `WAF-REL05-C3`, `WAF-REL05-C5` 와 직접 연계. 관련 페이지 raw 추가 시 Claim cross-reference 가능. +- Spring Retry 및 Resilience4j Retry 가 Related examples 로 링크됨 — ca-tmpl 의 구체 구현체 선택 시 참조. + +## Related / 관련 + +- 같은 주제 다른 official-doc: [[raw/official-docs/outbound-resilience4j-vs-spring-retry]] (존재 시) +- 이 자료를 인용한 wiki 요약: `[[wiki/concepts/retry-backoff-pattern]]` (생성 시) +- AWS Builder's Library retry/backoff 상세: https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/ (raw 추가 권고) diff --git a/vault/20-evidence/official-docs/retry-spring-retry-readme-backoff-defaults.md b/vault/20-evidence/official-docs/retry-spring-retry-readme-backoff-defaults.md new file mode 100644 index 0000000..7e8b539 --- /dev/null +++ b/vault/20-evidence/official-docs/retry-spring-retry-readme-backoff-defaults.md @@ -0,0 +1,91 @@ +--- +title: Spring Retry README — maxAttempts default & exponential backoff 설정 조건 +source_type: official-doc +url: https://github.com/spring-projects/spring-retry/blob/main/README.md +archive_url: +related_branches: [feature-background-job-async-contract] +related_projects: [ca-skeleton] +tags: [official-doc, ca-skeleton, application, spring-boot, circuit-breaker] +created: 2026-06-11 +--- + +# Spring Retry README — maxAttempts default & exponential backoff 설정 조건 + +> Layer: `raw/` — Spring Retry 공식 저장소 README 원문 발췌·출처 기록. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 `source-summary-template` 형식으로 별도 작성. 원본은 raw에 영구 보관. + +## Parent / 활용 branch (필수, 최소 1개+) + +> 이 자료는 혼자 존재하지 않는다. 어느 branch(또는 project)의 구현 결정의 근거로서 보관됨. + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-background-job-async-contract]] | D4 — `@Retryable` 의 maxAttempts default = 3 verbatim 확인; exponential+jitter 는 라이브러리 default 가 아니라 `multiplier > 1.0` + `random=true` 명시 설정 필요 (`@Backoff` default 는 명시 없음) | + +## 출처 / Source + +- 원본 URL: https://github.com/spring-projects/spring-retry/blob/main/README.md +- 아카이브 URL: (미설정) +- 저자 / 조직: Spring Projects (Pivotal / VMware / Broadcom) +- 발행일: (README — 지속 갱신, main 브랜치 HEAD) +- 마지막 확인일: 2026-06-11 + +## 왜 저장했는지 / Why archived + +`feature-background-job-async-contract` D4 결정 ("기본 backoff = exp+jitter, max=3") 이 `UNSUPPORTED_DECISION` 으로 표시되어 있어, Spring Retry 공식 README 에서 (1) maxAttempts default 값 verbatim 과 (2) exponential+jitter 가 명시 설정 없이는 활성화되지 않음을 근거로 확보하기 위해 보관. + +## 핵심 인용 / Key quotes (verbatim, 3~5문장) + +> [§ Declarative Retry] "This example calls the `service` method and, if it fails with a `RemoteAccessException`, retries (by default, up to three times), and then tries the `recover` method if unsuccessful." + +> [§ Exponential Backoff Rationale] "A common use case is to back off with an exponentially increasing wait period, to avoid two retries getting into lock step and both failing (a lesson learned from Ethernet)." + +> [§ @Backoff delay+maxDelay example] "The preceding example creates a random backoff between 100 and 500 milliseconds and up to 12 attempts." + +> [§ RetryTemplate Builder API] `.exponentialBackoff(100, 2, 10000)` — initial delay 100 ms, multiplier 2, max delay 10000 ms. Requires explicit builder call; not the default. + +> [§ Project Status] "⚠️ Project Status: Maintenance Only This project has been superseded by Spring Framework 7 and is no longer accepting enhancements." + +## Claims Extracted / 추출된 주장 + +> 이 자료가 직접 말하는 것만 claim 으로 분리한다. 내 프로젝트에 적용한 결론은 여기 쓰지 않는다. + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| SPRING-RETRY-C1 | `@Retryable` 의 default maxAttempts = 3 | [§ Declarative Retry] "retries (by default, up to three times)" | `official-vendor-doc` | Spring Retry `@Retryable` annotation 사용 시 | Spring Framework 7 native retry 또는 Resilience4j 의 default 값이 동일하다는 것을 증명하지 않음 | +| SPRING-RETRY-C2 | Exponential backoff with jitter 는 라이브러리 default 가 아니라 명시 설정 필요 (`multiplier` 와 `random` 파라미터를 명시해야 함) | [§ Exponential Backoff Rationale] "avoid two retries getting into lock step and both failing" + builder API `.exponentialBackoff(100, 2, 10000)` 는 explicit call 임 | `official-vendor-doc` | Spring Retry `@Backoff` / `RetryTemplate.builder()` 를 통한 retry 설정 | `@Backoff` 의 기본 `delay`, `multiplier`, `random` 수치를 명시하지 않음 (README 에서 default 값 표 미제공) | +| SPRING-RETRY-C3 | `@Backoff(delay=100, maxDelay=500)` 조합은 100~500 ms 사이의 random backoff 를 생성 | [§ @Backoff example] "creates a random backoff between 100 and 500 milliseconds" | `official-vendor-doc` | `delay` 와 `maxDelay` 를 모두 지정하고 둘 사이에 범위가 있을 때 | multiplier 를 명시하지 않은 경우의 정확한 분포(균등/지수)를 증명하지 않음 | +| SPRING-RETRY-C4 | Spring Retry 는 현재 maintenance 모드이며 Spring Framework 7 로 대체됨 | [§ Project Status] "superseded by Spring Framework 7 and is no longer accepting enhancements" | `official-vendor-doc` | Spring Retry 라이브러리 사용 여부 평가 시 | Spring Framework 7 의 retry 기능이 Spring Retry 와 기능 동등(feature parity) 함을 증명하지 않음 | + +### Strength 허용값 + +- 본 문서 claims 는 모두 `official-vendor-doc` — Spring Projects 공식 저장소 README. + +## Usage Boundaries / 적용 경계 + +- 이 자료가 직접 증명하는 것: + - `SPRING-RETRY-C1`: `@Retryable` 사용 시 별도 `maxAttempts` 지정 없으면 3회 시도 (2회 재시도) + - `SPRING-RETRY-C2`: exponential backoff 와 jitter 는 명시 설정 없이는 활성화되지 않음 — `.exponentialBackoff()` 또는 `@Backoff(multiplier=..., random=true)` 를 코드에서 직접 명시해야 함 + - `SPRING-RETRY-C3`: `delay` 와 `maxDelay` 를 함께 쓰면 그 사이 random backoff 생성 + - `SPRING-RETRY-C4`: 신규 기능 추가는 없고 유지보수 모드 +- 이 자료가 증명하지 않는 것: + - `@Backoff` 의 기본 `delay` 수치 (README 에서 명시하지 않음) + - `@Backoff` 의 기본 `multiplier` 수치 (README 에서 명시하지 않음) + - `@Backoff` 의 기본 `random` 값 (`false`/`true` — README 에서 명시하지 않음) + - Resilience4j 와의 기능 비교 (별도 raw 자료 필요) + - Spring Framework 7 의 retry API 가 Spring Retry 의 모든 기능을 대체하는지 여부 +- 내 프로젝트에 적용하려면 추가 확인이 필요한 것: + - ca-tmpl 에서 실제 `@Retryable(maxAttempts=3, backoff=@Backoff(multiplier=2, random=true))` 또는 동등 설정을 코드에서 명시하고, `locally-verified` 등급으로 승급 + - `@Backoff` 파라미터 실제 default 값 확인 필요 시 Spring Retry source (`@Backoff.java`) 직접 조회 권고 + +## 메모 / Notes + +- D4 의 `UNSUPPORTED_DECISION` 은 본 자료로 부분 해소: maxAttempts=3 은 default 임이 SPRING-RETRY-C1 으로 확인됨. exp+jitter 는 default 가 아니라 "명시 설정 필요" 임이 SPRING-RETRY-C2 로 확인됨. +- D4 의 "DLQ after exhausted" 부분은 본 README 에서 다루지 않음 — DLQ 패턴은 별도 raw 자료 (예: Spring Retry `RecoveryCallback` 공식 doc 또는 messaging 플랫폼 DLQ doc) 로 보완 필요. +- `@Backoff` 의 정확한 default 수치 (delay=1000?, multiplier=1.0?) 는 README 미명시 — source 코드 또는 Javadoc 으로만 확인 가능. 확인 전 `needs-confirmation`. +- Spring Retry 가 maintenance 모드 (SPRING-RETRY-C4) 이므로 신규 프로젝트에서는 Spring Framework 7 dependency 확인 권고. + +## Related / 관련 + +- 같은 주제 다른 official-doc: [[raw/official-docs/outbound-resilience4j-vs-spring-retry]] (Resilience4j vs Spring Retry 비교) +- 이 자료를 인용한 wiki 요약: `[[wiki/concepts/retry-backoff-contract]]` (생성 시) diff --git a/vault/20-evidence/official-docs/rfc3339-datetime-utc.md b/vault/20-evidence/official-docs/rfc3339-datetime-utc.md new file mode 100644 index 0000000..fc4f644 --- /dev/null +++ b/vault/20-evidence/official-docs/rfc3339-datetime-utc.md @@ -0,0 +1,109 @@ +--- +title: RFC 3339 — Date and Time on the Internet (Timestamps, UTC, "Z" Offset) +source_type: official-doc +url: https://www.rfc-editor.org/rfc/rfc3339 +archive_url: +status: raw +confidence: high +tags: [datetime, timestamp, utc, iso8601, rfc, ietf-standards-track, serialization, schema] +related_projects: [] +related_branches: [feature-runtime-health-lifecycle-contract, feature-schema-serialization-contract] +created: 2026-05-27 +last_reviewed: 2026-05-27 +--- + +# RFC 3339 — Date and Time on the Internet (Timestamps) + +> Layer: `raw/official-docs/` — IETF RFC 3339 (Standards Track, 2002-07) 발췌. Internet protocol 의 timestamp 표현 — ISO 8601 의 profile. UTC 의무, "Z" suffix 의 정확한 의미, ABNF 기반 date-time 문법 정의의 normative reference. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-runtime-health-lifecycle-contract]] | D12 — 모든 timestamp (health endpoint timestamp, startup time, last-checked) 를 UTC 로 직렬화하고 "Z" suffix 강제하는 표준 근거 | +| [[raw/branch-notes/feature-schema-serialization-contract]] | API response / event payload 의 datetime 직렬화 형식 (Jackson `JavaTimeModule` + `WRITE_DATES_AS_TIMESTAMPS=false` → RFC 3339 string) 표준 근거 | + +## 컨텍스트 + +서버/클라이언트 timezone 혼동, daylight saving 으로 인한 ambiguity, "2026-05-27 14:30" 같은 local 시각의 비호환성 문제를 막기 위한 운영 계약. ca-tmpl 의 health/lifecycle 응답과 schema serialization contract 모두 RFC 3339 + UTC + "Z" 를 baseline 으로 강제하려면 1차 표준 근거 필요. + +## 출처 / Source + +- 원본 URL: https://www.rfc-editor.org/rfc/rfc3339 +- 텍스트 버전: https://www.rfc-editor.org/rfc/rfc3339.txt +- 아카이브 URL: (미수집) +- 저자 / 조직: IETF — G. Klyne (Clearswift Corporation), C. Newman (Sun Microsystems) +- 발행일: 2002-07 (RFC 3339 Standards Track) +- 관련: ISO 8601 (profile of), RFC 2822 (Internet Mail date/time format), JSON Schema `format: date-time` +- 마지막 확인일: 2026-05-27 (curl + sed 로 본문 verbatim 발췌. WebFetch 본문은 quote style 차이 있어 정식 텍스트 버전을 SSOT 로 사용) + +## 왜 저장했는지 / Why archived + +ca-tmpl 의 runtime health endpoint 와 schema serialization contract 가 "datetime 은 RFC 3339 UTC `Z` suffix 만 허용" 을 baseline 으로 강제하는 결정의 normative 근거. company tech blog (Naver / Toss) 의 UTC-only 사례를 "best practice" 로 부르려면 본 RFC 가 standard 으로 corroborate 해야 함. + +## 핵심 인용 / Key quotes (verbatim, 2026-05-27 capture via `curl` + `sed -n`) + +> [§2 Definitions, line 164] "Z A suffix which, when applied to a time, denotes a UTC offset of 00:00; often spoken "Zulu" from the ICAO phonetic alphabet representation of the letter "Z"." + +> [§4.1 Coordinated Universal Time (UTC), line 213] "Because the daylight saving rules for local time zones are so convoluted and can change based on local law at unpredictable times, true interoperability is best achieved by using Coordinated Universal Time (UTC). This specification does not cater to local time zone rules." + +> [§4.3 Unknown Local Offset Convention, line 256] "If the time in UTC is known, but the offset to local time is unknown, this can be represented with an offset of "-00:00". This differs semantically from an offset of "Z" or "+00:00", which imply that UTC is the preferred reference point for the specified time." + +> [§5.6 Internet Date/Time Format, line 401] "The following profile of ISO 8601 [ISO8601] dates SHOULD be used in new protocols on the Internet. This is specified using the syntax description notation defined in [ABNF]." + +> [§5.6 ABNF, line 415] "time-offset = "Z" / time-numoffset" + +> [§5.6 ABNF, line 421] "date-time = full-date "T" full-time" + +> [§5.6 NOTE, line 432] "Applications that generate this format SHOULD use upper case letters." + +> [§5.8 Examples, line 515] "1985-04-12T23:20:50.52Z" + +## Claims Extracted / 추출된 주장 + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| RFC3339-C1 | "Z" suffix 는 UTC offset 00:00 을 의미. ICAO 음성기호 "Zulu" 에서 유래 | [§2 Definitions, line 164] "Z A suffix which, when applied to a time, denotes a UTC offset of 00:00; often spoken "Zulu" from the ICAO phonetic alphabet representation of the letter "Z"." | `official-standard` | RFC 3339 timestamp 의 "Z" suffix 해석 | "Z" 와 "+00:00" 의 의미론적 동등성 — `RFC3339-C3` 가 부분적으로 corroborate (§4.3 가 "Z" 와 "+00:00" 는 UTC preferred reference 의미, "-00:00" 와 의미상 다름) | +| RFC3339-C2 | true interoperability 는 UTC 사용으로 달성됨 — daylight saving rule 의 복잡성 + 예측 불가 변경 때문. 본 spec 은 local timezone rule 을 다루지 않음 | [§4.1, line 213] "Because the daylight saving rules for local time zones are so convoluted and can change based on local law at unpredictable times, true interoperability is best achieved by using Coordinated Universal Time (UTC). This specification does not cater to local time zone rules." | `official-standard` | Internet protocol 간 timestamp 교환의 baseline 권고 | "UTC 만 허용" 의 normative MUST 는 아님 — `best achieved by` 는 권고. 단 numeric offset 도 RFC 3339 가 허용 (§4.2) | +| RFC3339-C3 | UTC 가 알려졌으나 local offset 미상이면 `-00:00` 으로 표현. 이는 `Z` 또는 `+00:00` (둘 다 UTC 가 preferred reference 임을 의미) 와 **의미상 다름** | [§4.3, line 256] "If the time in UTC is known, but the offset to local time is unknown, this can be represented with an offset of "-00:00". This differs semantically from an offset of "Z" or "+00:00", which imply that UTC is the preferred reference point for the specified time." | `official-standard` | "-00:00" vs "Z"/"+00:00" 의 의미 구분 — UTC reference 의도 표시 여부 | 모든 client/parser 가 이 구분을 구현한다는 뜻은 아님 — 많은 라이브러리가 `-00:00` 와 `+00:00` 를 동일 취급 (구현 한계, 표준 의도와 분리) | +| RFC3339-C4 | 본 RFC 의 date/time format 은 ISO 8601 의 profile 이며, 새 Internet protocol 에서 **SHOULD** 사용 | [§5.6, line 401] "The following profile of ISO 8601 [ISO8601] dates SHOULD be used in new protocols on the Internet. This is specified using the syntax description notation defined in [ABNF]." | `official-standard` | 새 Internet protocol 설계 시 datetime 형식 선택 | 기존 protocol 의 다른 형식 (예: RFC 2822 email Date header) 을 금지한다는 뜻은 아님 — RFC 3339 는 **new** protocols 에 SHOULD | +| RFC3339-C5 | ABNF: `time-offset = "Z" / time-numoffset` — offset 은 `Z` 또는 명시적 numeric offset (`+`/`-` HH:MM) 만 허용 | [§5.6, line 415] "time-offset = "Z" / time-numoffset" | `official-standard` | RFC 3339 timestamp parser/serializer 의 offset 부분 문법 | "EST", "KST" 같은 alphabetic timezone 약어는 RFC 3339 timestamp 에 허용되지 않음 (ABNF 에 의해 함의) | +| RFC3339-C6 | ABNF: `date-time = full-date "T" full-time` — date 와 time 은 대문자 "T" 로 구분 | [§5.6, line 421] "date-time = full-date "T" full-time" | `official-standard` | RFC 3339 timestamp 의 date-time separator 문법 | `note` 에 따르면 lower-case "t"/"z" 도 ABNF 에 의해 허용되나 (§5.6 NOTE), 생성 시 대문자 SHOULD 권장 — `RFC3339-C7` 와 함께 해석 | +| RFC3339-C7 | 본 format 을 generate 하는 application 은 대문자 letters SHOULD 사용 | [§5.6 NOTE, line 432] "Applications that generate this format SHOULD use upper case letters." | `official-standard` | RFC 3339 timestamp 생성 시 대소문자 정책 | parser 가 lower-case 를 reject 해도 되는지는 본 인용에 직접 없음 — `RFC3339-C6` 의 ABNF NOTE 에 따르면 lower-case 도 valid syntactically | +| RFC3339-C8 | RFC 3339 timestamp 예시: `1985-04-12T23:20:50.52Z` — date "T" time fractional-seconds "Z" 형식 | [§5.8 Examples, line 515] "1985-04-12T23:20:50.52Z" | `official-standard` | RFC 3339 timestamp 구체적 표현 예시 (UTC + fractional seconds) | fractional seconds 의 자릿수 제한은 없음 (`time-secfrac = "." 1*DIGIT`) — 본 예시는 2자리 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것**: + - `RFC3339-C1`~`C3`: "Z" 의 정확한 의미 (UTC offset 00:00, "Zulu") + UTC interoperability 권고 + `-00:00` 의 의미 구분 + - `RFC3339-C4`~`C7`: ISO 8601 profile 의 normative status + ABNF 문법 + 대문자 권고 + - `RFC3339-C8`: timestamp 의 구체적 표현 예시 +- **이 자료가 증명하지 않는 것**: + - "UTC 만 허용" 의 strict MUST — RFC 3339 는 numeric offset (예: `-08:00`) 도 valid syntactically (§4.2 + §5.6 ABNF) + - timezone 정보를 별도 필드로 분리하는 것 (예: `{"timestamp": "...Z", "tz": "Asia/Seoul"}`) — application 책임 + - Java `Instant` / Python `datetime` / JS `Date` 가 RFC 3339 를 default 로 직렬화하는지 (각 언어/라이브러리 vendor 책임 — Jackson `JavaTimeModule`, Joda-Time, `tzdata` 등 별도 검증) + - "yyyy-MM-ddTHH:mm:ss" (Z 없는 naive datetime) 가 RFC 3339 invalid 라는 점은 ABNF (`full-time = partial-time time-offset`, time-offset 필수) 가 함의하나 본 발췌에 직접 인용 없음 + - JSON Schema `format: date-time` 이 RFC 3339 를 강제하는 것은 JSON Schema spec 의 정의 — 본 RFC 범위 밖 +- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: + - ca-tmpl 의 Jackson 설정 (`WRITE_DATES_AS_TIMESTAMPS=false`, `JavaTimeModule`) 이 `Instant.now()` 를 `2026-05-27T07:00:00Z` 형식으로 직렬화하는지 (실제 응답 검증) + - health endpoint timestamp 가 모두 UTC 인지 (서버 timezone 이 KST 여도 직렬화는 Z 로 강제되는지) + - MySQL `DATETIME` (timezone 없음) vs `TIMESTAMP` (UTC 저장) 의 선택과 RFC 3339 직렬화의 일관성 (DB layer 별도 검증) + +## 메모 / Notes + +- WebFetch 가 §2 의 "Z" 정의를 정확히 반환하지 않아 (quote style 차이) `curl https://www.rfc-editor.org/rfc/rfc3339.txt` + `sed -n` 으로 raw text 직접 추출. 모든 line number 는 텍스트 버전 기준. +- ABNF 의 `time-numoffset = ("+" / "-") time-hour ":" time-minute` (offset 의 정확한 syntax) 는 본 raw 에 별도 인용 없음 — `RFC3339-C5` 의 `time-offset` 이 부분적으로 corroborate. 필요 시 §5.6 line 414 별도 발췌. +- §4.4 "Unqualified Local Time" (timezone 없는 naive datetime — RFC 3339 가 명시적으로 discourage) 도 발췌 후보 — 본 raw 에 포함 안됨. +- ISO 8601:2019 (최신 ISO 표준) 와 RFC 3339 (2002) 의 차이 — RFC 3339 는 더 제한적인 profile. 별도 raw 또는 wiki/concepts source-summary 에서 다룸. + +## Related / 관련 + +- 같은 주제 다른 official-doc: + - ISO 8601 (RFC 3339 가 profile 로 삼은 표준) + - draft-ietf-sedate-datetime-extended (timezone 정보를 RFC 3339 timestamp 에 부착하는 후속 draft) +- 인용하는 branch: + - [[raw/branch-notes/feature-runtime-health-lifecycle-contract]] (D12) + - [[raw/branch-notes/feature-schema-serialization-contract]] +- 인용하는 project: + - [[raw/project-notes/ca-skeleton-operational-contract]] +- 인용한 wiki 요약: (미작성) diff --git a/vault/20-evidence/official-docs/rfc3986-uri-generic-syntax.md b/vault/20-evidence/official-docs/rfc3986-uri-generic-syntax.md new file mode 100644 index 0000000..28dbc31 --- /dev/null +++ b/vault/20-evidence/official-docs/rfc3986-uri-generic-syntax.md @@ -0,0 +1,94 @@ +--- +title: "official-doc / RFC 3986 — URI Generic Syntax (Berners-Lee et al., IETF, January 2005)" +source_type: official-doc +url: https://www.rfc-editor.org/rfc/rfc3986 +archive_url: +related_branches: [feature-resource-identifier-contract] +related_projects: [ca-skeleton] +tags: [official-doc, ca-skeleton, api-design, networking, api-contract] +created: 2026-05-31 +--- + +# RFC 3986 — URI Generic Syntax + +> Layer: `raw/` — 외부 자료(공식 문서)의 **원문 발췌·출처 기록**. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 `source-summary-template` 형식으로 별도 작성. 원본은 raw에 영구 보관. + +## Parent / 활용 branch (필수, 최소 1개+) + +> 이 자료는 **혼자 존재하지 않는다.** 어느 branch의 구현 결정의 **근거**로서 보관됨. + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-resource-identifier-contract]] | D2 (charset / encoding) — URL path 에서 안전한 문자 집합 정의 + D3 (URL-safe + case sensitivity) — `unreserved` 문자 집합 정의 및 scheme·host 는 case-insensitive, path 는 case-sensitive 라는 normalization 규칙 | + +## 출처 / Source + +- 원본 URL: https://www.rfc-editor.org/rfc/rfc3986 +- 아카이브 URL: (미설정) +- 저자 / 조직: Tim Berners-Lee, Roy T. Fielding, Larry Masinter — IETF (Internet Engineering Task Force) +- 발행일: January 2005 (Standards Track, STD 66) +- 마지막 확인일: 2026-05-31 + +## 왜 저장했는지 / Why archived + +ca-skeleton 의 resource ID 형식 결정 (branch: `feature-resource-identifier-contract`) 에서 URL path 에 허용된 문자 집합과 대소문자 정규화 규칙을 normative standard 로 확정해야 한다. RFC 3986 은 URI generic syntax 의 IETF 표준 사양이며, `unreserved` 문자 집합 (`ALPHA / DIGIT / "-" / "." / "_" / "~"`) 과 path component 의 case-sensitivity 정책을 규범적으로 정의하므로 D2·D3 결정의 최고 등급 근거(`official-standard`)로 보관한다. + +## 핵심 인용 / Key quotes (verbatim, 5문장) + +> [§2.3] "Characters that are allowed in a URI but do not have a reserved purpose are called unreserved. These include uppercase and lowercase letters, decimal digits, hyphen, period, underscore, and tilde." + +> [§2.3 ABNF] `unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"` + +> [§2.2] "URIs that differ in the replacement of a reserved character with its corresponding percent-encoded octet are not equivalent. Percent-encoding a reserved character, or decoding a percent-encoded octet that corresponds to a reserved character, will change how the URI is interpreted by most applications." + +> [§6.2.2.1] "When a URI uses components of the generic syntax, the component syntax equivalence rules always apply; namely, that the scheme and host are case-insensitive and therefore should be normalized to lowercase." + +> [§6.2.2.1] "The other generic syntax components are assumed to be case-sensitive unless specifically defined otherwise by the scheme (see Section 6.2.3)." + +## Claims Extracted / 추출된 주장 + +> 이 자료가 **직접 말하는 것만** claim 으로 분리한다. 내 프로젝트에 적용한 결론은 여기에 쓰지 않는다. + +| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | +|---|---|---|---|---|---| +| RFC3986-C1 | URI 에서 예약 목적 없이 사용할 수 있는 문자(unreserved)는 ALPHA, DIGIT, 하이픈, 마침표, 밑줄, 물결표이며 ABNF 로 `ALPHA / DIGIT / "-" / "." / "_" / "~"` 로 정의된다 | [§2.3] "Characters that are allowed in a URI but do not have a reserved purpose are called unreserved. These include uppercase and lowercase letters, decimal digits, hyphen, period, underscore, and tilde." + ABNF `unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"` | `official-standard` | RFC 3986 을 따르는 모든 URI | base64 표준(+, /, =), base62(대소문자+숫자만) 등 다른 encoding 의 URL-safety 를 직접 평가하지 않음 | +| RFC3986-C2 | reserved 문자를 percent-encode 하거나 reserved 문자에 해당하는 percent-encoded octet 을 decode 하면 URI 의 의미가 달라진다 | [§2.2] "URIs that differ in the replacement of a reserved character with its corresponding percent-encoded octet are not equivalent. Percent-encoding a reserved character, or decoding a percent-encoded octet that corresponds to a reserved character, will change how the URI is interpreted by most applications." | `official-standard` | URI 에서 gen-delims / sub-delims 를 데이터로 사용해야 하는 모든 경우 | reserved 문자의 구체적인 처리 방식(scheme-specific 허용 여부)은 각 scheme 사양에서 정의됨 | +| RFC3986-C3 | URI path component (및 기타 generic syntax component) 는 scheme 이 달리 정의하지 않는 한 case-sensitive 로 가정해야 한다 | [§6.2.2.1] "The other generic syntax components are assumed to be case-sensitive unless specifically defined otherwise by the scheme (see Section 6.2.3)." | `official-standard` | HTTP(S) URI path 를 비교·normalize 해야 하는 모든 구현 | scheme 이 명시적으로 case-insensitive 를 선언한 component 에는 적용되지 않음 | +| RFC3986-C4 | scheme 과 host component 는 case-insensitive 이므로 lowercase 로 normalize 해야 한다 | [§6.2.2.1] "When a URI uses components of the generic syntax, the component syntax equivalence rules always apply; namely, that the scheme and host are case-insensitive and therefore should be normalized to lowercase." | `official-standard` | 모든 RFC 3986 준수 URI 구현 | path / query / fragment 에는 이 case-insensitive 규칙이 적용되지 않음 | +| RFC3986-C5 | URI path 의 pchar 는 unreserved / pct-encoded / sub-delims / ":" / "@" 로 구성된다 | [§3.3 ABNF] `pchar = unreserved / pct-encoded / sub-delims / ":" / "@"` | `official-standard` | URI path segment 에 포함될 수 있는 문자를 결정해야 하는 구현 | pchar 에 sub-delims (!, $, &, ' 등) 포함이 허용된다고 해서 resource ID 에 자유롭게 사용해도 됨을 의미하지 않음 — ID 의 ID format policy 는 별도 결정 필요 | + +## Usage Boundaries / 적용 경계 + +- **이 자료가 직접 증명하는 것:** + - RFC3986-C1: URL path 에 percent-encoding 없이 안전하게 사용할 수 있는 문자는 정확히 `ALPHA / DIGIT / "-" / "." / "_" / "~"` 임. + - RFC3986-C2: `+`, `/`, `=` (base64 standard charset) 는 reserved 또는 non-unreserved 문자이므로 path segment 에 raw 사용 불가. URL-safe base64 (`-`, `_`) 는 unreserved 에 포함됨. + - RFC3986-C3: HTTP URI path (resource ID 포함) 는 case-sensitive 이며, `abc` 와 `ABC` 는 다른 자원을 가리킬 수 있음. + - RFC3986-C4: `http://` 와 `HTTP://`, `example.com` 과 `EXAMPLE.COM` 은 동등하게 정규화되어야 함. + - RFC3986-C5: path segment 에 허용되는 전체 문자 집합의 상한(pchar). + +- **이 자료가 증명하지 않는 것:** + - 특정 ID format (UUID, ULID, NanoID 등) 중 무엇을 선택해야 하는지 — 그것은 ID format policy 결정. + - base32 Crockford 나 base62 같은 encoding 이 RFC 3986 unreserved charset 의 부분집합인지 — 추가 분석 필요 (단, RFC3986-C1 의 chareset 정의로 부분집합 여부 판정 가능). + - case-insensitive ID format (예: ULID base32) 을 lowercase normalize 해야 하는지 여부 — RFC 는 path 가 case-sensitive 라고만 말하며, 어플리케이션 레벨 normalize 정책은 추가 결정 사항. + - percent-encoding 을 실제로 수행해야 하는 시점의 구체적인 구현 방법. + +- **ca-skeleton 에 적용하려면 추가 확인이 필요한 것:** + - ULID 의 Crockford base32 charset (`0-9A-Z`, case-insensitive) 이 RFC3986-C1 unreserved 의 부분집합임을 확인 (ALPHA + DIGIT 이므로 부분집합이지만, uppercase 고정 시 path case-sensitive 규칙과의 정합 확인 필요). + - NanoID 기본 charset (`A-Za-z0-9_-`) 이 RFC3986-C1 unreserved 의 부분집합임을 확인 (`_`, `-` 포함이므로 부분집합). + - base64 standard (`+/=`) 를 포함하는 ID format 사용 금지 — RFC3986-C1·C2 로 직접 차단. + +## 메모 / Notes + +- RFC 3986 은 2005년 발행 STD 66 으로, 현재까지 HTTP URI 의 normative standard. HTTP/1.1, HTTP/2, HTTP/3 모두 이 spec 을 참조함. +- `unreserved` charset 에 `~` (tilde) 가 포함되어 있음 — 일부 legacy 구현이 `%7E` 로 인코딩하는 경우가 있으나 RFC3986-C1 에 따르면 decode 되어야 함 (§6.2.2.2 Percent-Encoding Normalization 참조). +- path 의 경우 `pchar` (C5) 에 sub-delims 포함이 허용되지만, resource ID 는 delimiter 로 오해될 가능성을 배제하기 위해 unreserved charset 만 사용하는 것이 safe subset 전략. +- 추가로 봐야 할 동일 출처 섹션: §6.2.2.2 Percent-Encoding Normalization (unreserved 문자의 percent-encoded octet decode 권고), §6.2.2.3 Path Segment Normalization (dot-segment 제거). + +## Related / 관련 + +- 같은 주제 다른 official-doc (예정): + - [[raw/official-docs/rfc9562-uuid.md]] — UUID v4·v7 format spec (D1 결정 근거) + - [[raw/official-docs/ulid-spec.md]] — ULID 26자 base32 + monotonic spec (D1 결정 근거) + - [[raw/official-docs/google-aip-122-resource-names.md]] — Google AIP-122 resource name 정책 (D6 prefix 정책 참조) +- 이 자료를 인용할 wiki 요약: `wiki/concepts/uri-charset-and-case-normalization` (생성 시) diff --git a/vault/20-evidence/official-docs/rfc6455-websocket.md b/vault/20-evidence/official-docs/rfc6455-websocket.md new file mode 100644 index 0000000..cfb6665 --- /dev/null +++ b/vault/20-evidence/official-docs/rfc6455-websocket.md @@ -0,0 +1,95 @@ +--- +title: "official-doc / IETF RFC 6455 — The WebSocket Protocol" +source_type: official-doc +url: https://www.rfc-editor.org/rfc/rfc6455.html +archive_url: +related_branches: [feature-streaming-response-contract] +related_projects: [ca-skeleton] +tags: [websocket, rfc6455, ietf, full-duplex, tcp, http-upgrade, streaming, protocol, bidirectional] +created: 2026-06-02 +last_reviewed: 2026-06-02 +--- + +# IETF RFC 6455 — The WebSocket Protocol + +> Layer: `raw/official-docs/` — IETF RFC 6455 (December 2011, Standards Track) 핵심 섹션 발췌. +> Strength 분류: `official-standard` — IETF Standards Track RFC. +> 검증된 요약은 `/ingest` 후 `wiki/concepts/` 에 별도 작성. + +## Parent / 활용 branch (필수) + +| Branch | 이 자료가 정당화하는 결정 | +|---|---| +| [[raw/branch-notes/feature-streaming-response-contract]] | WebSocket alternative 의 프로토콜 명세 근거 — full-duplex, HTTP Upgrade handshake, frame 구조, TCP 관계, 보안 요구사항 (client masking) | + +## 출처 / Source + +- 원본 URL: https://www.rfc-editor.org/rfc/rfc6455.html +- Datatracker URL: https://datatracker.ietf.org/doc/html/rfc6455 +- 아카이브 URL: (미수집) +- 저자 / 조직: IETF — I. Fette (Google), A. Melnikov (Isode Ltd) +- 발행일: 2011-12 (December 2011, Proposed Standard / Standards Track) +- 마지막 확인일: 2026-06-02 + +## 왜 저장했는지 / Why archived + +`feature-streaming-response-contract` 에서 WebSocket 은 SSE 와 함께 핵심 비교 alternative. RFC 6455 는 WebSocket 의 유일한 normative specification. full-duplex 특성, HTTP → WebSocket upgrade 메커니즘, 클라이언트 프레임 masking 요구사항, TCP 와의 관계를 claim 수준으로 확인하기 위해 보관. 특히 "HTTP 와 독립된 TCP-based 프로토콜" 정의가 ca-skeleton 의 reverse proxy 설정 부담 claim 의 근거. + +## 핵심 인용 / Key quotes (verbatim) + +> [Abstract] "The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code. The security model used for this is the origin-based security model commonly used by web browsers. The protocol consists of an opening handshake followed by basic message framing, layered over TCP." + +> [Abstract] "The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers that does not rely on opening multiple HTTP connections (e.g., using XMLHttpRequest or