Skip to content

docs: establish canonical commercial architecture baseline - #149

Draft
seonghobae wants to merge 50 commits into
developfrom
docs/canonical-architecture-baseline-622e5e6
Draft

docs: establish canonical commercial architecture baseline#149
seonghobae wants to merge 50 commits into
developfrom
docs/canonical-architecture-baseline-622e5e6

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Purpose

Establish one code-current acquisition-diligence documentation graph over exact protected develop@622e5e6c3d534f230c390f10e3832efadfc01825. Active PRs/issues, chat, statuses, and synthetic merge previews remain evidence inputs, never shipped truth.

Exact current identity

  • base branch / independently resolved live tip: develop@622e5e6c3d534f230c390f10e3832efadfc01825;
  • branch: docs/canonical-architecture-baseline-622e5e6;
  • exact current source head: e7f7e7399fc0d1ea00724e59912bd332aef1bddb;
  • current synthetic merge preview: 9318881297ef6a45962e5bfbe5908dbdfb32df3b;
  • Draft / GitHub mergeability: true / true;
  • exact comparison from second RED e1c74748b00a59879422d7389244636501a70a7a: two non-destructive descendant commits, zero behind, changing only docs/DOCUMENTATION_ASSESSMENT.md and docs/TRACEABILITY.md.

No check, review, approval, base snapshot, body claim, or merge preview transfers across a source-head change.

Canonical graph and whole-conversation verdict

The branch contains current PRD, TRD, root Architecture, Security, ADR index plus ADR-0001..0014, UML, ERD/logical artifact model, API Contract, Threat Model, Test Strategy, Operability, Traceability, Documentation Assessment, AGENTS/CLAUDE/README/CHANGELOG alignment, and machine-checkable contracts.

The active documentation line is substantially design-sufficient; protected develop is still acquisition-documentation insufficient.

present_current is honest design authority, not protected implementation. Issue #159 remains the protected-integration/live-reconciliation completion tracker.

Cross-cutting decisions added test-first

  • ADR-0009 — Flyway-only schema mutation and provenance-bound backup/restore/recovery;
  • ADR-0010 — separate gateway, direct ETL, CDC, Eureka, Config Server, operator, and connector identity;
  • ADR-0011 — stable non-sensitive diagnostics, terminal DLT quarantine, governed retention/deletion/redrive;
  • ADR-0012 — exact, complete, non-vacuous quality/security/review/release evidence;
  • ADR-0013 — semantic-category runtime identifier and stateful compatibility migration;
  • ADR-0014 — Proposed one-tenant-per-deployment versus shared-runtime data-lifecycle authority; principal scoping is not tenant isolation.

Architecture/UML now cover identity, Flyway/recovery, DLT, and evidence/release flows. ERD separates protected relational truth from conceptual/external tenant_scope, service_identity, backup_bundle, backup_manifest_record, dead_letter_record, and external_effect_record; no table is invented from target design.

RED → GREEN evidence

  1. RED d76c2846f6827a9cf64d673576476cba642f66dd, CI 31382315597, macOS 93435001901: all prior documentation tests green; nine new assertions failed exactly for missing ADR/Architecture/UML/ERD authority.
  2. Candidate 21ec7b2bb454d59b9f9cb9aebf2ca094fac9b369: added ADR-0009..0014 and current Architecture/UML/ERD. CI exposed one stale lexical assertion requiring synthetic-merge rather than canonical synthetic merge.
  3. 5780011a4e2d5c4df0dcd6bc2e03e03d7cf3b2bb: fixed that brittle punctuation assertion without weakening source-identity semantics.
  4. Second RED e1c74748b00a59879422d7389244636501a70a7a, CI 31384214890, macOS 93440928100: canonical/live tests green except one intended fitness/Traceability assertion; ETL 262 tests, one failure, zero errors/skips.
  5. Exact GREEN e7f7e7399fc0d1ea00724e59912bd332aef1bddb: Assessment and Traceability recognize the now-present authorities without promoting active behavior.

Current CI 31384861240, macOS job 93442900410, checked out synthetic merge 9318881297ef6a45962e5bfbe5908dbdfb32df3b. It proves:

  • CrossCuttingArchitectureAuthorityTest: 10/10;
  • CanonicalDocumentationContractTest: 8/8;
  • LiveCommercialTraceabilityTest: 7/7;
  • ETL: 262/262;
  • CDC: 106/106;
  • gateway: 3/3;
  • full reactor: success.

The same job still reports Analyzed bundle 'etl-service' with 0 classes and then declares coverage checks met. That is explicitly non-acceptable coverage evidence under issue #162/PR #164 and repository-wide issue #205.

Exact current gates

For source head e7f7e7399fc0d1ea00724e59912bd332aef1bddb:

  • CI 31384861240: success on Ubuntu, macOS, and Windows;
  • Dependency Review 31384861247: success;
  • CycloneDX SBOM 31384861218: success;
  • SAST Semgrep 31384861286: success;
  • Security Scan 31384861146: aggregate success;
  • all current review threads: resolved;
  • formal review state: CodeRabbit COMMENTED only;
  • qualifying independent non-author exact-head formal APPROVED: absent.

CI and scanners executed the synthetic merge preview, not literal source. Issue #196 dependency-graph completeness and #162/#164/#205 non-vacuous coverage remain independent acceptance gates. Aggregate green is not merge or release authority.

Live work preserved as unshipped

Traceability covers #121, #139, #141#148, #155#169, #170/#171/#172/#174/#176/#211, #184, #189, #191/#192/#197/#199/#201/#208, #222/#224/#226/#228/#230/#236, and issue #151/#154/#159/#161/#162/#165/#185/#186/#187/#196/#205. Mutable SHAs and run IDs remain dated evidence rather than timeless Architecture.

Scope and merge boundary

This PR does not implement active product/security/recovery work, choose a license, invent certification/SLO/RPO/RTO/DR attainment, mutate separately leased repositories, or publish a release. Keep Draft until the unchanged exact head has accepted literal/subject-bound deterministic and security evidence, complete dependency materialization, non-vacuous applicable coverage, zero valid unresolved findings, current live-base integrity, and qualifying independent review.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

mightyETL의 저장소 운영 정책과 제품 문서를 보호된 develop 기준으로 전면 갱신했습니다. ETL·CDC·Gateway 계약, 상태 분류, 보안 경계, 자동화 권한, ADR, canonical 문서 및 문서 계약 테스트를 추가하거나 재작성했습니다.

Changes

운영 정책과 자동화 권한

Layer / File(s) Summary
운영 정책과 검증 게이트
AGENTS.md, CLAUDE.md, SECURITY.md
writer lease, exact-head 검증, RCA, TDD, PII 보호, 권한 분리, 보안 및 릴리스 게이트를 정의했습니다.

제품 상태와 아키텍처

Layer / File(s) Summary
제품 상태와 서비스 구조
ARCHITECTURE.md, PRD.md, README.md, SUMMARY_KR.md
보호된 develop의 구현 상태를 기준으로 ETL 원자성·멱등성, durable job, Debezium CDC, connector 범위, 배포 구조 및 known gap을 문서화했습니다.

기술·API 계약

Layer / File(s) Summary
기술 및 API 계약
TRD.md, docs/API_CONTRACT.md
HTTP·이벤트 호환성, 오류 형식, 영속성 상태, 인증 경계, CDC 전달, durable job 및 검증 증거 요구사항을 정의했습니다.

Canonical 문서와 검증

Layer / File(s) Summary
Canonical 문서 체계
CHANGELOG.md, docs/DOCUMENTATION_ASSESSMENT.md, docs/ERD.md, docs/OPERABILITY.md, docs/TEST_STRATEGY.md, docs/THREAT_MODEL.md, docs/TRACEABILITY.md, docs/UML.md, docs/adr/*
문서 상태 taxonomy, 추적성, 운영 절차, 위협 모델, ERD·UML 및 8개 ADR을 추가했습니다.
문서 계약 테스트
etl-service/src/test/java/com/xtrmetl/etl/documentation/*
필수 문서, API·영속성 계약, 상태 분류, 내부 링크, 형식 및 문서 간 일관성을 검증하도록 테스트를 변경했습니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 canonical 문서와 상용 아키텍처 기준선을 수립하는 주요 변경 내용을 명확하고 간결하게 요약합니다.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/canonical-architecture-baseline-622e5e6

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Please review exact current head 15c000a644796ef72e071dcd745dd4cf89feb38a against protected develop@622e5e6c3d534f230c390f10e3832efadfc01825. Focus on whether the canonical documentation and documentation-contract tests truthfully distinguish protected implementation from active PR/planned/superseded state, avoid inventing shipped APIs/security claims, and keep internal links/ADR/UML/ERD/API/threat/test/operability/traceability contracts consistent. Do not treat synthetic-merge workflow evidence as literal-head proof.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='622e5e6c3d534f230c390f10e3832efadfc01825'
head='15c000a644796ef72e071dcd745dd4cf89feb38a'

echo '== Repository HEAD and requested commits =='
git rev-parse HEAD
git cat-file -t "$base"
git cat-file -t "$head"
git show -s --format='BASE %H%n%P%n%s' "$base"
git show -s --format='HEAD %H%n%P%n%s' "$head"

echo '== Changed files, literal range =='
git diff --name-status "$base" "$head"

echo '== Documentation and test files in literal range =='
git diff --name-only "$base" "$head" | grep -E '(^|/)([^/]*\.(md|MD)|[^/]*(Test|Tests)\.(java|kt|ts|tsx|js|jsx|py|go|cs))$|(^|/)(docs|adr|api|threat|test|operability|traceability)(/|$)' || true

echo '== Root repository map =='
fd -HI -d 3 -t f -E .git | sed -n '1,300p'

echo '== Structural outline of changed source/test files =='
while IFS= read -r f; do
  case "$f" in
    *.java|*.kt|*.ts|*.tsx|*.js|*.jsx|*.py|*.go|*.cs)
      echo "--- $f"
      ast-grep outline "$f" --items all 2>/dev/null || true
      ;;
  esac
done < <(git diff --name-only "$base" "$head")

echo '== Diff: documentation and documentation-contract-related files =='
git diff --find-renames --find-copies --unified=80 "$base" "$head" -- \
  '*.md' '*.MD' '*Documentation*' '*documentation*' '*Contract*' '*contract*' \
  '*ADR*' '*adr*' '*UML*' '*uml*' '*ERD*' '*erd*' '*Threat*' '*threat*' \
  '*Traceability*' '*traceability*' '*Operability*' '*operability*' \
  '*Assessment*' '*assessment*' '*Api*' '*API*' || true

echo '== Protected-base implementation and API terminology =='
git grep -n -I -E \
  '(/auth/signin|/auth/signup|BCrypt|JWT|parallel.?batch|idempotenc|durable.?job|job.?status|atomic|transaction)' \
  "$base" -- ':!*.md' ':!*.MD' || true

Length of output: 6564


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='622e5e6c3d534f230c390f10e3832efadfc01825'
head='15c000a644796ef72e071dcd745dd4cf89feb38a'

echo '== Changed-file statistics =='
git diff --stat "$base" "$head"
echo

echo '== Changed Java test content at literal head =='
for f in \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/CanonicalDocumentationContractTest.java \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/DocumentationValidationTest.java
do
  echo "--- $f"
  git show "$head:$f" | nl -ba
done

echo '== New canonical document headings, links, and status vocabulary =='
for f in $(git diff --name-only --diff-filter=A "$base" "$head" -- 'docs/**'); do
  echo "--- $f"
  git show "$head:$f" | nl -ba | grep -E \
    '^[[:space:]]*[0-9]+[[:space:]]+(#|.*\]\(|.*implemented_on_develop|.*active_pr|.*planned|.*superseded|.*out_of_scope|.*PR #|.*PR #[0-9]+|.*endpoint|.*authentication|.*JWT|.*BCrypt|.*idempotenc|.*durable|.*atomic|.*parallel)' \
    || true
done

echo '== Root-document changed hunks =='
git diff --unified=30 "$base" "$head" -- \
  ARCHITECTURE.md CHANGELOG.md PRD.md README.md SECURITY.md SUMMARY_KR.md TRD.md

echo '== Markdown links in added canonical documents and their target existence at literal head =='
python3 - <<'PY'
import subprocess, re, posixpath
base = '622e5e6c3d534f230c390f10e3832efadfc01825'
head = '15c000a644796ef72e071dcd745dd4cf89feb38a'
files = subprocess.check_output(
    ['git','diff','--name-only','--diff-filter=A',base,head,'--','docs/**'],
    text=True).splitlines()
all_files = set(subprocess.check_output(['git','ls-tree','-r','--name-only',head], text=True).splitlines())
pattern = re.compile(r'(?<!!)\[[^\]]*\]\(([^)\s]+)(?:\s+"[^"]*")?\)')
for f in files:
    text = subprocess.check_output(['git','show',f'{head}:{f}'], text=True, errors='replace')
    for lineno, line in enumerate(text.splitlines(), 1):
        for raw in pattern.findall(line):
            target = raw.strip('<>')
            if target.startswith(('#','http://','https://','mailto:')): continue
            target = target.split('#',1)[0].split('?',1)[0]
            if not target: continue
            resolved = posixpath.normpath(posixpath.join(posixpath.dirname(f), target))
            print(f'{f}:{lineno}: {raw} => {resolved}: {"OK" if resolved in all_files else "MISSING"}')
PY

echo '== Protected-base endpoint mappings and security implementations =='
git grep -n -I -E \
  '@(RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)|RequestMethod\.' \
  "$base" -- ':(glob)**/*.java' || true
git grep -n -I -E \
  '(BCrypt|Jwt|JWT|PasswordEncoder|SecurityFilterChain|Authentication|authorizeHttpRequests|permitAll)' \
  "$base" -- ':(glob)**/*.java' || true

echo '== Protected-base durable job and idempotency implementation symbols =='
git grep -n -I -E \
  '(Idempoten|idempoten|Durable|durable|JobStatus|jobStatus|`@Transactional`|TransactionTemplate|atomic)' \
  "$base" -- ':(glob)**/*.java' || true

Length of output: 5356


🏁 Script executed:

#!/bin/bash
set -u

base='622e5e6c3d534f230c390f10e3832efadfc01825'
head='15c000a644796ef72e071dcd745dd4cf89feb38a'

echo '== Literal-head documentation contract tests =='
for f in \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/CanonicalDocumentationContractTest.java \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/DocumentationValidationTest.java
do
  echo "--- $f"
  git show "$head:$f" | grep -n '^' || true
done

echo '== Complete new canonical documents at literal head =='
for f in \
  docs/API_CONTRACT.md \
  docs/DOCUMENTATION_ASSESSMENT.md \
  docs/ERD.md \
  docs/OPERABILITY.md \
  docs/TEST_STRATEGY.md \
  docs/THREAT_MODEL.md \
  docs/TRACEABILITY.md \
  docs/UML.md \
  docs/adr/README.md \
  docs/adr/0001-canonical-documentation-and-status.md \
  docs/adr/0002-atomic-etl-and-idempotency.md \
  docs/adr/0003-durable-job-database-authority.md \
  docs/adr/0004-cdc-delivery-and-lifecycle-truth.md \
  docs/adr/0005-gateway-identity-boundary.md \
  docs/adr/0006-exact-evidence-and-agent-authority.md \
  docs/adr/0007-standalone-msa-and-connector-truth.md \
  docs/adr/0008-purpose-bound-pii-controls.md
do
  echo "--- $f"
  git show "$head:$f" | grep -n '^' || true
done

echo '== Literal-head references to state labels and active PRs =='
git grep -n -I -E \
  '(implemented_on_develop|active_pr|planned|superseded|out_of_scope|PR #[0-9]+|`#142`|`#149`)' \
  "$head" -- '*.md' '*.MD' '*.java' || true

echo '== Markdown link target checks, added canonical documents =='
python3 - <<'PY'
import subprocess, re, posixpath
base='622e5e6c3d534f230c390f10e3832efadfc01825'
head='15c000a644796ef72e071dcd745dd4cf89feb38a'
files=subprocess.check_output(
 ['git','diff','--name-only','--diff-filter=A',base,head,'--','docs/**'],text=True).splitlines()
tree=set(subprocess.check_output(['git','ls-tree','-r','--name-only',head],text=True).splitlines())
rx=re.compile(r'(?<!!)\[[^\]]+\]\(([^)\s]+)')
for f in files:
  content=subprocess.check_output(['git','show',head+':'+f],text=True,errors='replace')
  for i,line in enumerate(content.splitlines(),1):
    for target in rx.findall(line):
      target=target.strip('<>').split('#',1)[0].split('?',1)[0]
      if not target or target.startswith(('http://','https://','mailto:')): continue
      resolved=posixpath.normpath(posixpath.join(posixpath.dirname(f),target))
      if resolved not in tree:
        print('MISSING {}:{} {} -> {}'.format(f,i,target,resolved))
PY

echo '== Protected-base Java routes =='
git grep -n -I -E \
  '@(RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)|RequestMethod\.' \
  "$base" -- '*.java' || true

echo '== Protected-base Java security implementation terms =='
git grep -n -I -E \
  '(BCrypt|Jwt|JWT|PasswordEncoder|SecurityFilterChain|Authentication|authorizeHttpRequests|permitAll)' \
  "$base" -- '*.java' || true

echo '== Protected-base Java durable job, idempotency, and transaction terms =='
git grep -n -I -E \
  '(Idempoten|idempoten|Durable|durable|JobStatus|jobStatus|`@Transactional`|TransactionTemplate|atomic)' \
  "$base" -- '*.java' || true

Length of output: 233047


🏁 Script executed:

#!/bin/bash
set -u

base='622e5e6c3d534f230c390f10e3832efadfc01825'
head='15c000a644796ef72e071dcd745dd4cf89feb38a'

echo '== Canonical Markdown fragment-anchor audit at literal head =='
python3 - <<'PY'
import re, subprocess, posixpath, unicodedata
head='15c000a644796ef72e071dcd745dd4cf89feb38a'
docs=[
 'README.md','SUMMARY_KR.md','PRD.md','TRD.md','ARCHITECTURE.md','SECURITY.md',
 'docs/UML.md','docs/ERD.md','docs/API_CONTRACT.md','docs/THREAT_MODEL.md',
 'docs/TEST_STRATEGY.md','docs/OPERABILITY.md','docs/TRACEABILITY.md',
 'docs/DOCUMENTATION_ASSESSMENT.md','docs/adr/README.md'
]
tree=set(subprocess.check_output(['git','ls-tree','-r','--name-only',head],text=True).splitlines())
content={}
for f in docs:
    content[f]=subprocess.check_output(['git','show',head+':'+f],text=True,errors='replace')
def slug(s):
    s=unicodedata.normalize('NFKD',s).lower()
    s=re.sub(r'[`*_~]','',s)
    s=re.sub(r'[^\w\s-]','',s,flags=re.UNICODE)
    return re.sub(r'[\s-]+','-',s).strip('-')
anchors={}
for f,text in content.items():
    counts={}
    for line in text.splitlines():
        m=re.match(r'^\s{0,3}#{1,6}\s+(.+?)\s*#*\s*$',line)
        if m:
            a=slug(m.group(1)); n=counts.get(a,0); counts[a]=n+1
            anchors.setdefault(f,set()).add(a if n==0 else a+'-'+str(n))
rx=re.compile(r'(?<!!)\[[^\]]+\]\(([^)\s]+)')
for f,text in content.items():
  for lineno,line in enumerate(text.splitlines(),1):
    for raw in rx.findall(line):
      link=raw.strip('<>')
      if link.startswith(('http://','https://','mailto:')): continue
      path,sep,frag=link.partition('#')
      target=f if not path else posixpath.normpath(posixpath.join(posixpath.dirname(f),path))
      if target not in tree:
          print('MISSING_FILE {}:{} {}'.format(f,lineno,link))
      elif sep and target in anchors and slug(frag) not in anchors[target]:
          print('MISSING_ANCHOR {}:{} {} -> {}#{}'.format(f,lineno,link,target,slug(frag)))
PY

echo '== Literal-head documentation source-path references absent from its tree =='
python3 - <<'PY'
import re, subprocess
head='15c000a644796ef72e071dcd745dd4cf89feb38a'
docs=subprocess.check_output(
 ['git','diff','--name-only','622e5e6c3d534f230c390f10e3832efadfc01825',head,'--','*.md','*.MD'],
 text=True).splitlines()
tree=set(subprocess.check_output(['git','ls-tree','-r','--name-only',head],text=True).splitlines())
rx=re.compile(r'`((?:[\w.-]+/)+[\w.-]+(?:\.[\w.-]+)?)`')
for f in docs:
 text=subprocess.check_output(['git','show',head+':'+f],text=True,errors='replace')
 for i,line in enumerate(text.splitlines(),1):
  for path in rx.findall(line):
   if path not in tree and not path.startswith(('http://','https://')):
    print('POSSIBLE_MISSING_SOURCE_REFERENCE {}:{} {}'.format(f,i,path))
PY

echo '== Protected-base migration/bootstrap files matching ERD references =='
git ls-tree -r --name-only "$base" | grep -E \
  '(^|/)(01_schema\.sql|V1__create_etl_idempotency_records\.sql|V2__create_etl_job_records\.sql)$' || true

echo '== Protected-base controller configuration and response details =='
for f in \
  etl-service/src/main/java/com/xtrmetl/etl/controller/EtlJobController.java \
  etl-service/src/main/java/com/xtrmetl/etl/controller/EtlController.java \
  zuul-gateway/src/main/java/com/xtrmetl/gateway/security/JwtAuthenticationFilter.java \
  etl-service/src/main/resources/db/migration/V2__create_etl_job_records.sql
do
  echo "--- $f"
  git show "$base:$f" 2>/dev/null | grep -n -E \
    '(Conditional|RequestMapping|PostMapping|GetMapping|ResponseEntity|Location|Cache-Control|valid_token|job_status|CHECK|CREATE TABLE|Idempotency|Authentication)' || true
done

echo '== Status-claim enforcement inside the new literal-head contract test =='
git show "$head:etl-service/src/test/java/com/xtrmetl/etl/documentation/CanonicalDocumentationContractTest.java" \
  | grep -n -E \
    '(active_pr|implemented_on_develop|planned|superseded|out_of_scope|known_gap|`#121`|`#139`|`#142`|`#143`|`#148`|assertTrue)' || true

Length of output: 11850


@seonghobae I reviewed literal head 15c000a644796ef72e071dcd745dd4cf89feb38a against protected develop@622e5e6c3d534f230c390f10e3832efadfc01825.

I found two documentation-contract issues.

  1. README.md Line 257 links to LICENSE, but the literal head has no LICENSE file. This breaks the internal-link contract. DocumentationValidationTest.readmeInternalLinksResolve() should fail on this target.

  2. CanonicalDocumentationContractTest does not verify capability-to-status relationships. For example, Lines 54–83 only require implemented_on_develop and active_pr to occur somewhere in the root documents. The test remains green if POST /api/etl/jobs/{job_record_id}/cancellation, CANCELLED, or a Resource Server JWT claim is relabeled implemented_on_develop, provided active_pr still occurs elsewhere. Add assertions that bind each protected API/state to implemented_on_develop and each open-PR API/state to active_pr.

The protected-base code supports the main corrected claims. It contains the documented ETL and CDC routes, feature-gated durable intake/status, principal-scoped idempotency, and the literal valid_token gateway placeholder. I did not use synthetic-merge evidence as literal-head proof.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AGENTS.md`:
- Around line 104-108: Update the “Standards, research, and commercial
readiness” section by replacing the misspelled `doctoring/ADRs` reference with
the repository’s canonical documentation and ADR directory paths, so
contributors record APA 7 references in the correct locations.

In `@ARCHITECTURE.md`:
- Line 133: Implement bounded retention for etl_job_records.request_payload:
define TTL, purge payloads on terminal states, handle cleanup failures, and
restore cleanup behavior after restart, with migration and lifecycle tests
covering these paths. Update ARCHITECTURE.md lines 133-133 and PRD.md lines
304-321 to document the same retention contract; if implementation is deferred,
mark the capability as a known_gap and restrict production use instead.
- Line 279: Update the sentence beginning with “#121” so the issue identifier is
enclosed in Markdown backticks, preventing it from being interpreted as a
heading; leave the rest of the sentence unchanged.

In `@docs/API_CONTRACT.md`:
- Around line 143-154: Update the Problem Details contract to match
EtlApiProblemHandler’s problem.setInstance(...) response field by documenting
instance instead of path, unless an explicit path alias is implemented. Keep the
documented public fields aligned with the actual response and add or update
contract tests to lock in the chosen field name.

In `@docs/ERD.md`:
- Around line 73-75: Update the `etl_job_records` section in `docs/ERD.md` so
terminal-state `request_payload` clearing is not presented as implemented in
protected `develop`; mark it as `known_gap` or `active_pr` until the
corresponding migration and integration tests exist. Keep the documented active
and terminal status values, and retain the statement that protected develop
lacks lease, pagination, cancellation, and replay-lineage fields.

In `@docs/TEST_STRATEGY.md`:
- Around line 131-140: Update docs/TEST_STRATEGY.md lines 131-140 to include
known_gap in the canonical status taxonomy and require each capability status to
be validated against source-backed claims. Update docs/TRACEABILITY.md line 39
so the Status value is planned, moving the partial scaffold detail into the
Source / persistence or Evidence column.

In
`@etl-service/src/test/java/com/xtrmetl/etl/documentation/CanonicalDocumentationContractTest.java`:
- Around line 120-129: Replace the standalone status-token checks with
capability-to-status assertions. In
etl-service/src/test/java/com/xtrmetl/etl/documentation/CanonicalDocumentationContractTest.java:120-129,
bind protected contracts such as POST /api/etl/process, etl_idempotency_records,
and etl_job_records to documentation entries marked implemented_on_develop. In
etl-service/src/test/java/com/xtrmetl/etl/documentation/DocumentationValidationTest.java:149-158,
bind cancellation, CANCELLED, and Resource Server JWT claims to their exact
active_pr or known_gap statuses, ensuring unrelated status labels cannot satisfy
the tests.

In
`@etl-service/src/test/java/com/xtrmetl/etl/documentation/DocumentationValidationTest.java`:
- Around line 57-59: Restore the approved LICENSE file referenced by README.md
so DocumentationValidationTest.readmeInternalLinksResolve passes without
weakening the internal-link contract; if no license has been authorized, remove
the README LICENSE link instead and resolve the deployment policy before
changing the test.

In `@PRD.md`:
- Line 230: NFR-REL-1 heading을 현재 ####에서 ###로 변경해 `## 5. Non-Functional
Requirements` 아래의 계층을 한 단계씩 따르도록 수정하세요.

In `@README.md`:
- Line 22: README.md의 Databricks / Snowflake / Qlik status를 canonical 상태인
known_gap으로 변경하고, Notes 설명에는 scaffold-only를 유지하세요. 다른 상태 라벨이나 문서 구조는 변경하지 마세요.

In `@SECURITY.md`:
- Around line 67-69: Update the PR `#139` entry in SECURITY.md to replace “finite
future waiting” with the established “bounded acknowledgement wait/retry
boundary” terminology, matching ARCHITECTURE.md and PRD.md while preserving the
surrounding remediation contract description.

In `@TRD.md`:
- Around line 24-30: Update the Spring Boot and Spring Cloud version entries in
TRD.md to match the root pom.xml Maven properties: 3.5.16 and 2025.0.3. Leave
the already aligned Java and Debezium entries unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ed81746a-f995-4246-a2d3-41c9abaf21d2

📥 Commits

Reviewing files that changed from the base of the PR and between 622e5e6 and 132d223.

📒 Files selected for processing (28)
  • AGENTS.md
  • ARCHITECTURE.md
  • CHANGELOG.md
  • CLAUDE.md
  • PRD.md
  • README.md
  • SECURITY.md
  • SUMMARY_KR.md
  • TRD.md
  • docs/API_CONTRACT.md
  • docs/DOCUMENTATION_ASSESSMENT.md
  • docs/ERD.md
  • docs/OPERABILITY.md
  • docs/TEST_STRATEGY.md
  • docs/THREAT_MODEL.md
  • docs/TRACEABILITY.md
  • docs/UML.md
  • docs/adr/0001-canonical-documentation-and-status.md
  • docs/adr/0002-atomic-etl-and-idempotency.md
  • docs/adr/0003-durable-job-database-authority.md
  • docs/adr/0004-cdc-delivery-and-lifecycle-truth.md
  • docs/adr/0005-gateway-identity-boundary.md
  • docs/adr/0006-exact-evidence-and-agent-authority.md
  • docs/adr/0007-standalone-msa-and-connector-truth.md
  • docs/adr/0008-purpose-bound-pii-controls.md
  • docs/adr/README.md
  • etl-service/src/test/java/com/xtrmetl/etl/documentation/CanonicalDocumentationContractTest.java
  • etl-service/src/test/java/com/xtrmetl/etl/documentation/DocumentationValidationTest.java

Comment thread AGENTS.md
Comment thread ARCHITECTURE.md Outdated
Comment thread ARCHITECTURE.md Outdated
Comment thread docs/API_CONTRACT.md
Comment thread docs/ERD.md Outdated
Comment thread PRD.md Outdated
Comment thread README.md Outdated
Comment thread SECURITY.md Outdated
Comment thread TRD.md

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Please review exact current head e3f69c747ffdeae5212f9735b0d59e6562e344cc. The predecessor-head findings have been revalidated and addressed; do not reuse conclusions from older heads.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='622e5e6c3d534f230c390f10e3832efadfc01825'
head='e3f69c747ffdeae5212f9735b0d59e6562e344cc'

echo '== Commit identity =='
printf 'checked-out: '; git rev-parse HEAD
git cat-file -e "${base}^{commit}"
git cat-file -e "${head}^{commit}"
git show -s --format='base %H%nparents %P%nsubject %s' "$base"
git show -s --format='head %H%nparents %P%nsubject %s' "$head"

echo '== Literal diff name/status =='
git diff --name-status "$base" "$head"

echo '== Relevant changed files =='
git diff --name-only "$base" "$head" -- \
  '*.md' '*.MD' \
  'etl-service/src/test/java/com/xtrmetl/etl/documentation/*.java' \
  'etl-service/src/main/**/*.java' \
  'zuul-gateway/src/main/**/*.java'

echo '== Java test outline =='
for f in \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/CanonicalDocumentationContractTest.java \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/DocumentationValidationTest.java
do
  if git cat-file -e "$head:$f" 2>/dev/null; then
    echo "--- $f"
    git show "$head:$f" > "/tmp/$(basename "$f")"
    ast-grep outline "/tmp/$(basename "$f")" --items all || true
    nl -ba "/tmp/$(basename "$f")"
  fi
done

echo '== Current documentation status claims and API/state references =='
git grep -n -I -E \
  '(implemented_on_develop|active_pr|planned|superseded|known_gap|out_of_scope|CANCELLED|cancellation|Resource Server|JWT|valid_token|Idempotency-Key|/api/etl/jobs)' \
  "$head" -- '*.md' '*.MD' '*.java' || true

echo '== Literal-head Markdown link audit =='
python3 - <<'PY'
import posixpath, re, subprocess
head = 'e3f69c747ffdeae5212f9735b0d59e6562e344cc'
tree = set(subprocess.check_output(
    ['git', 'ls-tree', '-r', '--name-only', head], text=True).splitlines())
files = [p for p in tree if p.lower().endswith('.md')]
link = re.compile(r'(?<!!)\[[^\]]+\]\(([^)\s]+)')
for path in sorted(files):
    text = subprocess.check_output(
        ['git', 'show', f'{head}:{path}'], text=True, errors='replace')
    for line_no, line_text in enumerate(text.splitlines(), 1):
        for raw in link.findall(line_text):
            target = raw.strip('<>')
            if target.startswith(('http://', 'https://', 'mailto:', '#')):
                continue
            target = target.split('#', 1)[0].split('?', 1)[0]
            if not target:
                continue
            resolved = posixpath.normpath(posixpath.join(posixpath.dirname(path), target))
            if resolved not in tree:
                print(f'MISSING {path}:{line_no}: {raw} -> {resolved}')
PY

echo '== Protected-base literal route and security evidence =='
git grep -n -I -E \
  '@(RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)|RequestMethod\.' \
  "$base" -- '*.java' || true
git grep -n -I -E \
  '(valid_token|Jwt|JWT|SecurityFilterChain|Authentication|Idempoten|idempoten|Durable|durable|JobStatus|Transactional)' \
  "$base" -- '*.java' '*.sql' || true

echo '== Diff for current documentation contracts =='
git diff --unified=50 "$base" "$head" -- \
  README.md PRD.md TRD.md ARCHITECTURE.md SECURITY.md \
  'docs/**/*.md' \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/CanonicalDocumentationContractTest.java \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/DocumentationValidationTest.java

Length of output: 6735


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='622e5e6c3d534f230c390f10e3832efadfc01825'
old_head='15c000a644796ef72e071dcd745dd4cf89feb38a'
head='e3f69c747ffdeae5212f9735b0d59e6562e344cc'

show_numbered() {
  git show "$1:$2" | awk '{printf "%5d  %s\n", NR, $0}'
}

echo '== Documentation contract tests at literal head =='
for f in \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/CanonicalDocumentationContractTest.java \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/DocumentationValidationTest.java
do
  echo "--- $f"
  show_numbered "$head" "$f"
done

echo '== Changes from predecessor reviewed head to requested head =='
git diff --unified=40 "$old_head" "$head" -- \
  README.md PRD.md TRD.md ARCHITECTURE.md SECURITY.md \
  'docs/**/*.md' \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/CanonicalDocumentationContractTest.java \
  etl-service/src/test/java/com/xtrmetl/etl/documentation/DocumentationValidationTest.java

echo '== Status-bearing documentation lines at literal head =='
git grep -n -I -E \
  '(implemented_on_develop|active_pr|planned|superseded|known_gap|out_of_scope|CANCELLED|cancellation|Resource Server|JWT|valid_token|Idempotency-Key|/api/etl/jobs)' \
  "$head" -- '*.md' '*.MD' || true

echo '== Literal-head Markdown link audit =='
python3 - <<'PY'
import posixpath, re, subprocess
head = 'e3f69c747ffdeae5212f9735b0d59e6562e344cc'
tree = set(subprocess.check_output(
    ['git', 'ls-tree', '-r', '--name-only', head], text=True).splitlines())
link = re.compile(r'(?<!!)\[[^\]]+\]\(([^)\s]+)')
for path in sorted(p for p in tree if p.lower().endswith('.md')):
    text = subprocess.check_output(
        ['git', 'show', f'{head}:{path}'], text=True, errors='replace')
    for line_no, line_text in enumerate(text.splitlines(), 1):
        for raw in link.findall(line_text):
            target = raw.strip('<>')
            if target.startswith(('http://', 'https://', 'mailto:', '#')):
                continue
            target = target.split('#', 1)[0].split('?', 1)[0]
            if target:
                resolved = posixpath.normpath(posixpath.join(posixpath.dirname(path), target))
                if resolved not in tree:
                    print(f'MISSING {path}:{line_no}: {raw} -> {resolved}')
PY

echo '== Locate protected-base sources relevant to documented contracts =='
git ls-tree -r --name-only "$base" | grep -E \
  '(^|/)(Etl(Job)?Controller|JwtAuthenticationFilter|.*Security.*|V[0-9]+__.*(job|idempoten).*\.(java|sql))$' \
  || true

echo '== Protected-base route, status, and security evidence =='
git grep -n -I -E \
  '@(RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)|RequestMethod\.|valid_token|Jwt|JWT|SecurityFilterChain|Idempoten|idempoten|Durable|durable|JobStatus|Transactional' \
  "$base" -- '*.java' '*.sql' || true

Length of output: 222835


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='622e5e6c3d534f230c390f10e3832efadfc01825'
head='e3f69c747ffdeae5212f9735b0d59e6562e344cc'

echo '== README directory link and target =='
git show "$head:README.md" | awk 'NR >= 190 && NR <= 215 { printf "%5d  %s\n", NR, $0 }'
echo '-- tracked entries under docs/connectors --'
git ls-tree -r --name-only "$head" -- docs/connectors || true
echo '-- working-tree target type --'
if [ -d docs/connectors ]; then
  echo 'docs/connectors is a directory'
elif [ -e docs/connectors ]; then
  echo 'docs/connectors exists but is not a directory'
else
  echo 'docs/connectors does not exist'
fi

echo '== Maven version declarations at literal head =='
for f in $(git ls-tree -r --name-only "$head" | grep -E '(^|/)pom\.xml$'); do
  echo "--- $f"
  git show "$head:$f" | grep -n -E '(spring-boot|spring-cloud|3\.5\.|2025\.0\.)' || true
done

echo '== TRD runtime version statements =='
git show "$head:TRD.md" | awk 'NR >= 15 && NR <= 35 { printf "%5d  %s\n", NR, $0 }'

echo '== Protected-base ETL problem mapping and error statuses =='
for f in \
  etl-service/src/main/java/com/xtrmetl/etl/controller/EtlApiProblemHandler.java \
  etl-service/src/main/java/com/xtrmetl/etl/service/EtlRequestError.java
do
  echo "--- $f"
  git show "$base:$f" | awk '{printf "%5d  %s\n", NR, $0}' | \
    grep -E -C 4 '(HttpStatus|SERVICE_UNAVAILABLE|INTERNAL_SERVER_ERROR|TRANSIENT|503|500|Target|DataAccess)' \
    || true
done

echo '== Literal-head README retry statements and canonical problem contract =='
git show "$head:README.md" | awk 'NR >= 105 && NR <= 145 { printf "%5d  %s\n", NR, $0 }'
git show "$head:docs/api/problem-details.md" | awk 'NR <= 150 { printf "%5d  %s\n", NR, $0 }'

Length of output: 29239


@seonghobae I reviewed literal head e3f69c747ffdeae5212f9735b0d59e6562e344cc against protected develop@622e5e6c3d534f230c390f10e3832efadfc01825.

I found one documentation-contract gap.

  • CanonicalDocumentationContractTest.capabilityStatusesAreBoundToSourceBackedClaims() binds status rows only in docs/TRACEABILITY.md at Lines 133–152. It does not bind the same capability labels in docs/API_CONTRACT.md. For example, docs/API_CONTRACT.md currently marks POST /api/etl/jobs/{job_record_id}/cancellation and CANCELLED as active_pr, but a future change could relabel that API or state as implemented_on_develop while leaving its traceability row unchanged. Both documentation tests would still pass. Add assertions for the API contract’s active_pr cancellation and CANCELLED content. Add assertions for the protected durable intake/status API as implemented_on_develop as well.

The previous LICENSE finding does not apply to this head. README.md now removes the invalid link. The directory link to docs/connectors/ resolves. The revised status assertions correctly bind the traceability rows for cancellation, Resource Server JWT, gateway placeholder, and canonical CDC.

Protected-base source supports the documented ETL, idempotency, feature-gated durable intake, CDC, and valid_token gateway claims. I did not use synthetic-merge evidence as literal-head proof.

You are interacting with an AI system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant