Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
5261356
security: rebuild audit pseudonymization on current main
seonghobae Aug 5, 2026
28966e6
test(security): require strong policy override keys
seonghobae Aug 5, 2026
2e9c4a2
fix(security): reject weak policy override keys
seonghobae Aug 5, 2026
ac70dd7
docs(security): document policy override key strength
seonghobae Aug 5, 2026
27106a5
fix: trigger CI due to strix timeout
seonghobae Aug 5, 2026
b3ad882
chore: remove stray CI trigger script
seonghobae Aug 5, 2026
0e7770b
test: cover disabled policy signing startup path
seonghobae Aug 5, 2026
a86ab46
docs: consolidate unreleased changelog entries
seonghobae Aug 5, 2026
eb34323
build: enforce zero missed production lines and branches
seonghobae Aug 5, 2026
164aecf
ci: verify exact PR head with coverage gates
seonghobae Aug 5, 2026
294b30b
ci: fuzz the exact pull request head
seonghobae Aug 5, 2026
febb3fd
docs: record exact-head and coverage gates
seonghobae Aug 5, 2026
9cf1ff8
test: add shared security provider fixture
seonghobae Aug 5, 2026
3214bc0
test: cover null policy secret normalization
seonghobae Aug 5, 2026
62dac96
test: cover tenant delete fail-closed branches
seonghobae Aug 5, 2026
0416068
test: cover validation security edge cases
seonghobae Aug 5, 2026
6b61330
test: cover conversion filename boundary
seonghobae Aug 5, 2026
70f3399
test: cover artifact deletion failure
seonghobae Aug 5, 2026
d73571b
test: cover repository delete edge cases
seonghobae Aug 5, 2026
36254ee
test: cover exception log sanitization
seonghobae Aug 5, 2026
a1533de
test: cover download filename and digest edges
seonghobae Aug 5, 2026
31c4b4d
fix: redact rejected parameter values
seonghobae Aug 5, 2026
c0c0c45
docs: record rejected-value redaction
seonghobae Aug 5, 2026
a308f0f
test: cover every override header separator
seonghobae Aug 5, 2026
39dc005
refactor: trust normalized policy secret contract
seonghobae Aug 5, 2026
6e311ed
refactor: remove unreachable blank filename branch
seonghobae Aug 5, 2026
8ca8958
fix(ci): isolate exact-head evidence finalization runs
seonghobae Aug 5, 2026
61ab219
fix(ci): use repository-native evidence verifier
seonghobae Aug 5, 2026
2831bb9
docs(evidence): ingest verified Netty 4.1.136 evidence
github-actions[bot] Aug 5, 2026
fa1659a
fix(security): restore reviewed Netty 4.1.136 remediation
seonghobae Aug 5, 2026
6d9a3d7
test(evidence): verify complete Netty SBOM graph coherence
seonghobae Aug 5, 2026
20513e3
docs(security): record deterministic Netty SBOM provenance
seonghobae Aug 5, 2026
67cd42c
docs(evidence): correct CycloneDX generation contract
seonghobae Aug 5, 2026
06452c3
docs(changelog): record deterministic Netty buyer evidence
seonghobae Aug 5, 2026
1907593
test(security): require auditable policy overrides
seonghobae Aug 5, 2026
0189136
fix(security): fail closed without override audit key
seonghobae Aug 5, 2026
c57af8b
docs(security): require auditable override startup
seonghobae Aug 5, 2026
5073573
docs(changelog): record auditable override gate
seonghobae Aug 5, 2026
ff10462
test(security): require standalone override auditability
seonghobae Aug 5, 2026
f08d789
refactor(security): expose reusable override key validation
seonghobae Aug 5, 2026
9c33db4
fix(security): enforce override auditability in standalone service
seonghobae Aug 5, 2026
10bfb26
test(fuzz): use separated override audit keys
seonghobae Aug 5, 2026
162166a
test(web): use separated override audit keys
seonghobae Aug 5, 2026
967fe25
test(service): use separated override audit keys
seonghobae Aug 5, 2026
92ce1c6
test(audit): reject unauditable policy signing
seonghobae Aug 5, 2026
422c465
docs(security): cover standalone override validation
seonghobae Aug 5, 2026
cacd637
docs(changelog): record standalone override guard
seonghobae Aug 5, 2026
08b14b7
test(build): require warning-free public Javadocs
seonghobae Aug 5, 2026
f86581f
build(docs): gate warning-free public Javadocs
seonghobae Aug 5, 2026
c0d2c7b
docs(api): explain tenant context claims
seonghobae Aug 5, 2026
21bbc79
docs(api): explain conversion status payload
seonghobae Aug 5, 2026
648e71b
docs(api): explain admin job list payload
seonghobae Aug 5, 2026
f454056
docs(api): explain conversion acceptance payload
seonghobae Aug 5, 2026
8d3d180
docs(api): explain viewer bootstrap payload
seonghobae Aug 5, 2026
f96d7d4
docs(api): explain error response envelope
seonghobae Aug 5, 2026
4b1f65d
docs(api): complete public Javadocs
seonghobae Aug 5, 2026
e08e0e0
docs(api): finish warning-free Javadoc surface
seonghobae Aug 5, 2026
ecbc0a9
docs(changelog): record executable Javadoc gate
seonghobae Aug 5, 2026
fcc77fd
docs(agents): make verify and Javadocs authoritative
seonghobae Aug 5, 2026
58c9cff
docs(acceptance): make verify evidence authoritative
seonghobae Aug 5, 2026
bf7083d
docs(governance): use current sibling repository names
seonghobae Aug 5, 2026
91091dd
perf(io): remove filesystem TOCTOU prechecks
seonghobae Aug 5, 2026
dca468e
test(ci): require non-skipped Maven report acceptance
seonghobae Aug 5, 2026
231ce19
feat(ci): fail on skipped or empty Maven reports
seonghobae Aug 5, 2026
1e3d6f6
fix(ci): reject skipped or empty Maven test reports
seonghobae Aug 5, 2026
040909f
docs(ci): require zero-skipped Maven report evidence
seonghobae Aug 5, 2026
6ee5c40
docs(changelog): record zero-skipped CI gate
seonghobae Aug 5, 2026
b34b931
test(ci): require bounded entity-free XML reports
seonghobae Aug 5, 2026
eeee286
fix(ci): bound and sanitize Maven XML evidence
seonghobae Aug 5, 2026
fa25f04
docs(ci): define bounded XML report parsing
seonghobae Aug 5, 2026
9a83d0f
docs(changelog): record safe Maven report parsing
seonghobae Aug 5, 2026
7b6f60a
fix(ci): eliminate report size-check race
seonghobae Aug 5, 2026
98870b0
test(ci): reject encoded XML declaration bypasses
seonghobae Aug 5, 2026
72b30b6
fix(ci): enforce UTF-8 Maven report evidence
seonghobae Aug 5, 2026
08b31c1
docs(ci): require UTF-8 Maven XML evidence
seonghobae Aug 5, 2026
95b046a
docs(changelog): record encoded XML rejection
seonghobae Aug 5, 2026
a93127b
test(ci): reject failing Maven report evidence
seonghobae Aug 5, 2026
5d1040e
fix(ci): reject failing Maven report evidence
seonghobae Aug 5, 2026
fff6161
docs(ci): reject contradictory Maven outcomes
seonghobae Aug 5, 2026
3c9bea3
docs(changelog): record report outcome checks
seonghobae Aug 5, 2026
d089e6b
test(ci): assert singular Maven outcome diagnostics
seonghobae Aug 5, 2026
e3104fc
test: require complete Maven report counts
seonghobae Aug 5, 2026
260d98f
fix: reject incomplete Maven report counts
seonghobae Aug 5, 2026
6e7e864
docs: record fail-closed report attributes
seonghobae Aug 5, 2026
2656321
docs: define complete Maven report evidence
seonghobae Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 79 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,86 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Verify exact checked-out revision
env:
EXPECTED_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: test "$(git rev-parse HEAD)" = "$EXPECTED_SHA"
- name: Use preinstalled Temurin JDK 21
# Uses the runner image's bundled JDK instead of actions/setup-java to
# keep every workflow dependency hash-pinned (Scorecard Pinned-Dependencies).
run: |
echo "JAVA_HOME=$JAVA_HOME_21_X64" >> "$GITHUB_ENV"
echo "$JAVA_HOME_21_X64/bin" >> "$GITHUB_PATH"
- name: Run tests
run: mvn -B --no-transfer-progress test
- name: Run tests and coverage acceptance gates
shell: bash
run: |
if ! mvn -B --no-transfer-progress verify; then
if [[ -f target/site/jacoco/jacoco.csv ]]; then
echo "::group::JaCoCo CSV diagnostics"
cat target/site/jacoco/jacoco.csv
echo "::endgroup::"
fi
if [[ -f target/site/jacoco/jacoco.xml ]]; then
echo "::group::JaCoCo uncovered line diagnostics"
python3 - <<'PY'
import xml.etree.ElementTree as ET
from pathlib import Path

report = Path("target/site/jacoco/jacoco.xml")
root = ET.parse(report).getroot()
gaps = []
for package in root.findall("package"):
package_name = package.get("name", "")
for source_file in package.findall("sourcefile"):
source_name = source_file.get("name", "")
source_path = f"{package_name}/{source_name}" if package_name else source_name
for line in source_file.findall("line"):
missed_instructions = int(line.get("mi", "0"))
missed_branches = int(line.get("mb", "0"))
if missed_instructions or missed_branches:
gaps.append(
(
source_path,
int(line.get("nr", "0")),
missed_instructions,
missed_branches,
)
)

for source_path, line_number, missed_instructions, missed_branches in gaps:
print(
f"{source_path}:{line_number}: "
f"missed_instructions={missed_instructions} "
f"missed_branches={missed_branches}"
)
PY
echo "::endgroup::"
fi
exit 1
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.
python3 scripts/verify_maven_test_reports.py

merge-compatibility:
name: Maven merge compatibility
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Verify merge revision
env:
EXPECTED_SHA: ${{ github.sha }}
run: test "$(git rev-parse HEAD)" = "$EXPECTED_SHA"
- name: Use preinstalled Temurin JDK 21
run: |
echo "JAVA_HOME=$JAVA_HOME_21_X64" >> "$GITHUB_ENV"
echo "$JAVA_HOME_21_X64/bin" >> "$GITHUB_PATH"
- name: Verify merged result
run: |
mvn -B --no-transfer-progress verify
python3 scripts/verify_maven_test_reports.py

script-checks:
name: Buyer-readiness script tests
Expand All @@ -33,6 +105,11 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Verify exact checked-out revision
env:
EXPECTED_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: test "$(git rev-parse HEAD)" = "$EXPECTED_SHA"
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ jobs:
- TenantClaimsFuzzTest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Verify exact checked-out revision
env:
EXPECTED_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: test "$(git rev-parse HEAD)" = "$EXPECTED_SHA"

- name: Set up JDK 21
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961
Expand Down
36 changes: 25 additions & 11 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ including mandatory quality and security merge gates.

## Mandatory merge gates

- `mvn -DskipTests compile` must pass with warning/deprecated budget = 0.
- `mvn test` must pass.
- JaCoCo coverage for production package must remain 100% line/branch.
- JavaDoc gate must pass (`mvn -q -DskipTests javadoc:javadoc`) with no warnings/errors.
- `mvn -B --no-transfer-progress verify` is the authoritative local and CI
acceptance command. Do not substitute `compile`, `test`, or a predecessor
head result for this exact-head lifecycle.
- Java 21 compilation must pass with warning and deprecation budget = 0.
- Every test must pass with zero failures, errors, and skips.
- JaCoCo coverage for the `com.clearfolio.viewer.*` production package must
remain 100% statement/line and branch coverage, expressed as zero missed
production lines and branches.
- The verify lifecycle must generate public Javadocs with Maven Javadoc Plugin
3.12.0, `doclint=all`, `failOnError=true`, and `failOnWarnings=true`. Public
record components, constructors, methods, enum values, fields, parameters,
return values, and thrown failures must be understandable without reading the
implementation.
- Markdown lint for changed docs must pass.
- Security evidence must be attached on PR (SAST/code-scanning checks).
- CodeQL Java/Kotlin analysis must remain enabled through repository default
Expand All @@ -31,10 +40,15 @@ including mandatory quality and security merge gates.
`python3 scripts/summarize_buyer_readiness.py --manifest docs/diligence/2026-07-03-buyer-data-room-manifest.json --output docs/diligence/2026-07-03-buyer-readiness-scorecard.md --summary docs/qa/evidence/2026-07-02-krw2b-sale-readiness/buyer-readiness-scorecard-summary.json --check`.
- Figma Slides generation payload check must pass:
`python3 scripts/check_figma_deck_payload.py --payload docs/design/2026-07-03-buyer-diligence-slides-generation-payload.json --summary docs/qa/evidence/2026-07-02-krw2b-sale-readiness/figma-deck-payload-check.json`.
- `mvn test` includes `DependencyPolicyTest`, which prevents reintroducing the
broad `tika-parsers-standard-package`, default Logback starter, or excluded
Jakarta annotation dependency unless a future PR updates the license policy,
SBOM evidence, attribution package, and buyer diligence docs together.
- `mvn verify` includes `DependencyPolicyTest`, which prevents reintroducing the
broad `tika-parsers-standard-package`, default Logback starter, excluded
Jakarta annotation dependency, an unreviewed Netty version, or a weakened
public-Javadoc gate unless a future PR updates the corresponding security,
license, SBOM, attribution, acceptance, and buyer-diligence evidence together.
- CI, Security Scan, SAST Semgrep, every fuzz target, required organization
reviews, and branch protection must all pass on the exact current PR head.
Queued, pending, cancelled, skipped-required, stale-head, or predecessor-head
evidence is not passing.

## Change management rule

Expand All @@ -58,7 +72,7 @@ Codex, Cursor, opencode, …) working in this repo.
then **remediate**:
- This is a Maven / Spring Boot app — findings are almost always vulnerable
Java dependencies. Fix by bumping the offending artifact (or its managed
version) in `pom.xml`; re-run `mvn -DskipTests compile` and `mvn test`.
version) in `pom.xml`; re-run `mvn -B --no-transfer-progress verify`.
- There is currently no `Dockerfile` or k8s manifest here; if one is added,
trivy will also flag image/IaC misconfigs — fix those at the source.
- For a genuine false positive only, add a narrow, **documented**
Expand Down Expand Up @@ -108,11 +122,11 @@ Codex, Cursor, opencode, …) working in this repo.
DOM-decomposes emails and files into a persisted knowledge graph. Each
component is a standalone program that must ALSO work as a git submodule of
the hub, grown separately and together.
- Sibling components: **waf-ids-ai-soc** (WAF / IDS / AI SOC / LB / APIM),
- Sibling components: **wardnet** (WAF / IDS / AI SOC / LB / APIM),
**pg-erd-cloud** (ERD tool), **contextual-orchestrator** (LLM
cost/perf/upstream-LB gateway, beyond LiteLLM), **codec-carver** (STT /
omni-modal speech-video codec), **fast-mlsirm** (LLM-as-a-Judge calibration +
evaluation-item quality, using aFIPC FIPC + kaefa item-fit), **feelanet-adfs**
evaluation-item quality, using aFIPC FIPC + kaefa item-fit), **keyverse**
(passwordless SSO — OIDC/SCIM/ADFS/LDAP/FIDO2/OAuth2.1, eliminate passwords),
**newsdom-api** (PDF→DOM sidecar), and **semantic-data-portal** (upper
ontology / catalog / governance plane with its own graph engine).
Expand Down
44 changes: 31 additions & 13 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,46 @@
## [Unreleased]
### Added
- **UI UX 개선**: 'Details' 버튼 클릭 시, 작업 상세 정보 로드 중에 사용자가 명시적인 로딩 상태를 확인할 수 있도록 'Loading...' 텍스트와 비활성화 상태를 표시하도록 추가했습니다.

### Changed
- PDF.js WebJar를 `6.1.200`으로 올리고, Clearfolio가 동일 버전의 `pdf.mjs`와 `pdf.worker.mjs`를 직접 사용해 서명된 same-origin artifact의 첫 페이지를 렌더링하도록 통합했습니다. 패키징·셸 경로·서명된 `artifactToken` 흐름을 회귀 테스트로 고정했습니다.

# Changelog

## [Unreleased]

### 추가된 기능 (Added)
### Added

- **UI UX 개선**: 'Details' 버튼 클릭 시, 작업 상세 정보 로드 중에 사용자가 명시적인 로딩 상태를 확인할 수 있도록 'Loading...' 텍스트와 비활성화 상태를 표시하도록 추가했습니다.
- **관리자용 단건 작업 삭제 및 재시도 API 추가**
- 특정 변환 작업을 삭제할 수 있는 `DELETE /api/v1/admin/convert/jobs/{jobId}` 엔드포인트를 추가했습니다.
- 실패(dead-lettered) 상태인 작업을 관리자가 재시도 큐에 등록할 수 있는 `POST /api/v1/admin/convert/jobs/{jobId}/retry` 엔드포인트를 추가했습니다.

- **비동기 버튼 로딩 피드백 및 상태 복원 개선**
- KPI 스냅샷 증거를 다시 불러오는 `refreshKpiEvidence` 동작 중에 "Refresh evidence" 버튼을 비활성화하고 "Refreshing..." 이라는 피드백을 제공하여 사용자의 중복 클릭을 방지했습니다.
- KPI 스냅샷 증거를 다시 불러오는 `refreshKpiEvidence` 동작 중에 "Refresh evidence" 버튼을 비활성화하고 "Refreshing..."이라는 피드백을 제공하여 사용자의 중복 클릭을 방지했습니다.
- 버튼 상태 변경 시 내부 DOM 구조를 보존하기 위해 `Array.from(button.childNodes)`로 원래 노드를 저장하고, 성공 및 실패 후 `finally` 블록에서 `replaceChildren(...)`으로 안전하게 복원하도록 구현했습니다.

### Changed

- PDF.js WebJar를 `6.1.200`으로 올리고, Clearfolio가 동일 버전의 `pdf.mjs`와 `pdf.worker.mjs`를 직접 사용해 서명된 same-origin artifact의 첫 페이지를 렌더링하도록 통합했습니다. 패키징·셸 경로·서명된 `artifactToken` 흐름을 회귀 테스트로 고정했습니다.
- CI가 pull request의 정확한 head SHA를 명시적으로 체크아웃하고 검증하며, 합성 merge revision은 별도 호환성 작업에서 검증하도록 분리했습니다.
- Maven `verify` 단계에서 JaCoCo production line 및 branch missed count가 각각 0인지 강제하고, 실패 시 누락 위치 진단을 출력하도록 했습니다.
- Maven `verify` 이후 Surefire 보고서가 존재하고 실행 테스트 수가 1개 이상이며 skipped·failure·error 수가 모두 0인지 검증합니다. Failsafe 보고서가 생성된 경우 동일한 규칙을 적용하며, 보고서 누락·손상·음수 카운트·전체 skip·실패 결과는 exact-head CI와 merge-compatibility 모두에서 fail closed 처리합니다.
- Maven `verify` 단계에서 Java 21 public Javadocs를 `doclint=all`로 생성하고 warning 또는 error가 하나라도 발생하면 실패하도록 했습니다. 공개 record 구성요소, 생성자, enum 값, 필드와 매개변수 문서를 초보자도 코드 분석 없이 이해할 수 있는 수준으로 보완했습니다.
- Jazzer fuzzing도 pull request의 정확한 head SHA를 명시적으로 체크아웃하고 검증하도록 강화했습니다.
- CycloneDX Maven Plugin 2.9.1의 정확한 `outputFormat`/`outputName` 사용자 속성으로 생성한 61개 구성요소 SBOM과 제3자 고지문을 buyer evidence에 반영했습니다. 생성 source head, UTC 시각, artifact/archive/SBOM/attribution 해시, 17개 Netty 구성요소의 purl·bom-ref·dependency-edge 정합성, 로컬 생성 증거와 공유 가능한 데이터룸 증거의 경계를 ADR 및 실행 가능한 drift test로 고정했습니다.

### Security

- Maven XML 테스트 보고서 검증기는 각 `testsuite`의 `tests`, `skipped`, `failures`, `errors` 속성을 모두 필수 증거로 요구합니다. 누락된 결과 수를 암묵적으로 0으로 간주하지 않고 fail closed 처리하며, 각 속성 누락 회귀 테스트를 추가했습니다.
- Maven XML 테스트 보고서 검증기는 UTF-8만 허용하고 UTF-8 BOM은 수용하며, NUL 바이트·DTD·엔터티 선언을 파싱 전에 거부합니다. UTF-16 같은 대체 인코딩으로 위험 선언을 바이트 검사에서 숨기는 우회와 외부 엔터티 읽기·엔터티 확장형 서비스 거부를 회귀 테스트로 차단했습니다.
- Maven XML 테스트 보고서 검증기는 파일당 16 MiB 상한을 적용하고 한 번의 제한된 읽기로 실제 입력 크기를 검증합니다. 테스트 코드가 보고서 파일을 교체하거나 확장해도 크기 사전검사와 파싱 사이의 경쟁 조건을 이용할 수 없습니다.
- Spring Boot 3.5.16이 관리하던 Netty `4.1.135.Final` 전이 의존성 전체를 Spring Boot의 공식 `netty.version` 속성을 통해 `4.1.136.Final`로 정렬했습니다. 실제 POM을 읽는 회귀 테스트와 보안 ADR을 추가해 개별 Netty 모듈의 혼합 버전 및 향후 무의식적 downgrade를 차단했습니다.
- 정책 재정의 승인자의 원문 식별자를 감사 로그에서 제거하고, 전용 회전형 키와 도메인 분리를 사용하는 HMAC 기반 `approverFingerprint`로 대체했습니다. 정책 재정의 서명이 비활성화된 경우에만 전용 키 부재를 비상관 `unavailable` 표식으로 표현하며, 원문이나 비키 해시로 폴백하지 않습니다.
- 정책 재정의 서명 키를 활성화하면서 전용 감사 가명화 키를 누락하면 Spring 시작과 `DefaultDocumentValidationService`의 독립·모듈식 직접 생성을 모두 거부하도록 강화했습니다. 관리자 예외를 승인하면서 승인자별 상관 가능한 감사 증거를 남기지 못하는 구성을 모든 실행 모드에서 fail closed로 차단하고, 두 키의 최소 강도와 용도 분리를 유지합니다.
- 감사 가명화 키의 소유권, 회전, 보존, 사고 대응 및 GDPR상 가명정보의 개인정보 지위를 문서화하고, 원문 승인자 식별자와 승인 토큰이 로그에 남지 않는 회귀 테스트를 추가했습니다.
- 경로·쿼리 파라미터 타입 변환 실패 응답에서 사용자가 제출한 거부 값을 고정된 `[redacted]` 표식으로 대체해 오류 응답을 통한 개인정보·비밀값 반사를 차단했습니다. 값이 실제로 없었던 경우에만 `null` 진단을 유지합니다.

### Fixed

- 뷰어 UI의 재시도 버튼 로딩 상태가 내부 DOM을 손상시키지 않고 안전하게 복원되도록 수정했습니다.

## [0.1.0] - 2026-06-25

### 추가된 기능 (Added)

- **비동기 버튼 로딩 상태 UX 개선 (Async Button Loading States)**
- 문서 제출(`submitDocument`), 데모 데이터 로드(`loadDemoData`), 실패 작업 재시도(`retryActiveJob`) 등 비동기 요청을 수행하는 버튼들에 대해 처리 중 명시적인 로딩 상태(Loading, Submitting, Retrying 등)를 추가했습니다.
- 사용자의 중복 클릭을 방지하기 위해 작업 중에는 버튼이 비활성화되도록 수정했습니다.
Expand All @@ -37,9 +56,11 @@
- 관련 `AdminJobListResponse` DTO 모델과 이를 처리하는 Repository 및 Service 계층의 `findAll`/`getAllJobs` 메서드를 추가했습니다.

### 테스트 커버리지 (Tests)

- 신규 구현된 Repository, Service, Controller 계층에 대한 유닛 테스트(Unit Tests)를 작성하여 JaCoCo 기준 라인 및 브랜치 커버리지 100%를 달성했습니다.

### 보안 (Security)

- **의존성 취약점 일괄 정리 (trivy-fs / osv-scan 대응)**: Spring Boot 부모 POM을 `3.5.0`에서 `3.5.16`으로 올려 Spring Framework, Netty, Reactor Netty, logback 관련 다수의 HIGH/MEDIUM 권고를 해소했습니다.
- Jackson 계열을 `jackson-bom` import로 `2.22.1`에 고정하여 jackson-databind case-insensitive deserialization bypass 권고(GHSA-5jmj-h7xm-6q6v / CVE-2026-54515)를 제거했습니다.
- Apache Tika 표준 파서를 통해 유입되던 전이 의존성을 `dependencyManagement`로 고정했습니다: junrar `7.6.0`(경로 순회 RCE/파일 쓰기), commons-io `2.20.0`(XmlStreamReader DoS), commons-lang3 `3.18.0`, BouncyCastle `bcprov-jdk18on 1.84` 및 `bcpkix-jdk18on 1.84`(CRITICAL/Medium). 전체 347개 테스트 통과를 확인했습니다.
Expand All @@ -48,6 +69,3 @@
- 루트 `LICENSE`와 Maven license metadata를 추가해 Scorecard License alert가 표준 Apache-2.0 파일을 확인할 수 있게 했습니다.
- logback-core 신규 권고(GHSA-jhq6-gfmj-v8fx) 대응을 위해 Logback 관리 버전을 `1.5.35`로 고정했습니다.
- 저장소 보안 정책, Maven/GitHub Actions Dependabot 설정, 기본 CodeQL/중앙 SAST 운영 지침, 다운로드 파일명 정규화 Jazzer fuzz target을 추가해 Scorecard 보안 거버넌스 신호를 보강했습니다.

### Fixed
- 뷰어 UI의 재시도 버튼 로딩 상태가 내부 DOM을 손상시키지 않고 안전하게 복원되도록 수정
4 changes: 3 additions & 1 deletion docs/diagrams/submit-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ sequenceDiagram
V->>P: getBlockedExtensions()
alt Override headers valid
V-->>V: validate override=true + token + approver
V-->>V: emit audit-safe log(extension, approver, tokenFingerprint)
V-->>V: emit audit-safe log(extension, approverFingerprint, tokenFingerprint)
V-->>Svc: validation ok
else Override missing/invalid
V-->>Svc: UnsupportedDocumentFormatException or IllegalArgumentException
Expand Down Expand Up @@ -94,6 +94,8 @@ sequenceDiagram
end
```

`approverFingerprint` is the versioned, domain-separated keyed audit pseudonym. The raw approver identifier is accepted only as validation input and is never emitted by the audit-safe log.

## Exception paths covered

- Missing or empty file
Expand Down
Loading
Loading