Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
220 commits
Select commit Hold shift + click to select a range
61d19fb
test(conversion): define office adapter contract regression
seonghobae Aug 9, 2026
fa01cff
feat(conversion): add immutable Office conversion request
seonghobae Aug 9, 2026
3bd5b51
feat(conversion): add verified Office conversion result
seonghobae Aug 9, 2026
9e11b82
feat(conversion): classify Office conversion failures
seonghobae Aug 9, 2026
d508977
feat(conversion): add provider-neutral Office adapter interface
seonghobae Aug 9, 2026
624fa4a
fix(conversion): fail closed on missing job identity
seonghobae Aug 9, 2026
31cde21
test(conversion): cover fail-closed adapter validation branches
seonghobae Aug 9, 2026
a660298
test(conversion): require canonical source-format identity
seonghobae Aug 9, 2026
6ffe183
fix(conversion): canonicalize Office source format
seonghobae Aug 9, 2026
215b192
test(conversion): require canonical identity and typed failures
seonghobae Aug 9, 2026
10201a3
fix(conversion): canonicalize adapter request identity
seonghobae Aug 9, 2026
8850dff
feat(conversion): add typed Office adapter failure
seonghobae Aug 9, 2026
3ba542f
test(conversion): require adapter source provenance binding
seonghobae Aug 9, 2026
0f80c64
fix(conversion): enforce source-bound adapter results
seonghobae Aug 9, 2026
d6c8295
test(conversion): require full request generation binding
seonghobae Aug 9, 2026
0a58858
feat(conversion): bind immutable request authority
seonghobae Aug 9, 2026
115a5e0
feat(conversion): expose immutable request binding
seonghobae Aug 9, 2026
49a8607
feat(conversion): carry full request binding in results
seonghobae Aug 9, 2026
9ad4dc0
fix(conversion): reject stale request-bound output
seonghobae Aug 9, 2026
dd7c6dc
test(conversion): cover request-binding validation
seonghobae Aug 9, 2026
6f8fbf5
test(conversion): verify full request-bound results
seonghobae Aug 9, 2026
a101031
test(conversion): require deterministic fixture adapter
seonghobae Aug 9, 2026
189f235
feat(conversion): add deterministic fixture adapter
seonghobae Aug 9, 2026
f7c0437
test(conversion): require bound output size limit
seonghobae Aug 9, 2026
18e5ebf
feat(conversion): bind maximum output bytes
seonghobae Aug 9, 2026
2215a59
feat(conversion): include output ceiling in binding
seonghobae Aug 9, 2026
850e661
feat(conversion): classify oversized output
seonghobae Aug 9, 2026
368eb54
feat(conversion): reject oversized candidate PDFs
seonghobae Aug 9, 2026
cbf0628
test(conversion): require parseable PDF output
seonghobae Aug 9, 2026
6201aa1
feat(conversion): validate candidate PDF structure
seonghobae Aug 9, 2026
6d3146a
test(conversion): share parseable PDF fixture
seonghobae Aug 9, 2026
666d8ca
test(conversion): use parseable PDF for adapter success
seonghobae Aug 9, 2026
b1e6582
test(conversion): use parseable deterministic fixture output
seonghobae Aug 9, 2026
a7f7f33
fix(conversion): eliminate PDF validation compile warning
seonghobae Aug 9, 2026
7e5262e
test(conversion): use parseable PDF at exact output limit
seonghobae Aug 9, 2026
9549c74
test(conversion): reject zero-page PDF output
seonghobae Aug 9, 2026
d806ae3
fix(conversion): reject zero-page PDF output
seonghobae Aug 9, 2026
99c89d5
test(conversion): bind output to qualified adapter identity
seonghobae Aug 9, 2026
d163729
feat(conversion): bind requests to qualified adapter identity
seonghobae Aug 9, 2026
c9991a5
feat(conversion): include adapter version in request binding
seonghobae Aug 9, 2026
0b99611
fix(conversion): enforce qualified adapter provenance
seonghobae Aug 9, 2026
fe3f65b
test(conversion): align output-limit fixtures with bound adapter
seonghobae Aug 9, 2026
30bcc1e
test(conversion): align PDF fixtures with bound adapter
seonghobae Aug 9, 2026
f20aa09
test(conversion): require explicit adapter identity in public requests
seonghobae Aug 9, 2026
f97bfe4
test(conversion): require explicit adapter identity in public bindings
seonghobae Aug 9, 2026
508f653
fix(conversion): require adapter identity in public request API
seonghobae Aug 9, 2026
967a709
fix(conversion): require adapter identity in public binding API
seonghobae Aug 9, 2026
5cb089c
test(conversion): reject encrypted Office adapter PDFs
seonghobae Aug 9, 2026
3cbfa3c
fix(conversion): reject encrypted Office adapter PDFs
seonghobae Aug 9, 2026
7226e7e
test(conversion): bind and enforce PDF page ceiling
seonghobae Aug 9, 2026
ee17904
feat(conversion): bind PDF page ceiling to Office request
seonghobae Aug 9, 2026
416ca4d
feat(conversion): include PDF page ceiling in request binding
seonghobae Aug 9, 2026
2f7a1ba
feat(conversion): classify PDF page-limit failures
seonghobae Aug 9, 2026
d7a4a0a
fix(conversion): enforce request-bound PDF page ceiling
seonghobae Aug 9, 2026
948a80c
fix(conversion): preserve qualified adapter byte-limit constructor
seonghobae Aug 9, 2026
2cd4586
test(conversion): reject PDF JavaScript open actions
seonghobae Aug 9, 2026
70a4d67
fix(conversion): reject PDF document-open actions
seonghobae Aug 9, 2026
30dc093
test(conversion): reject document JavaScript name trees
seonghobae Aug 9, 2026
99882ab
fix(conversion): reject document JavaScript name trees
seonghobae Aug 9, 2026
fdfc65e
test(conversion): reject embedded PDF file name trees
seonghobae Aug 9, 2026
87c48f8
fix(conversion): reject embedded PDF file name trees
seonghobae Aug 9, 2026
bd2e628
test(conversion): reject PDF page additional actions
seonghobae Aug 9, 2026
fc29c32
fix(conversion): reject PDF page additional actions
seonghobae Aug 9, 2026
18a7f64
test(conversion): reject PDF catalog additional actions
seonghobae Aug 9, 2026
89b6137
fix(conversion): reject PDF catalog additional actions
seonghobae Aug 9, 2026
6add9bf
test(conversion): reject PDF annotation actions
seonghobae Aug 9, 2026
41c053d
test(conversion): target executable annotation actions
seonghobae Aug 9, 2026
3654cdd
fix(conversion): reject executable PDF annotation actions
seonghobae Aug 9, 2026
7d8b597
test(conversion): preserve inert PDF hyperlinks
seonghobae Aug 9, 2026
dc1498d
test(conversion): reject PDF associated files
seonghobae Aug 9, 2026
dccc963
fix(conversion): reject PDF associated files
seonghobae Aug 9, 2026
977fad8
test(conversion): reject PDF launch actions
seonghobae Aug 9, 2026
bc26275
fix(conversion): reject PDF launch actions
seonghobae Aug 9, 2026
e7a88eb
test(conversion): classify benign and active PDF actions
seonghobae Aug 9, 2026
79c65ce
fix(conversion): classify PDF actions by behavior
seonghobae Aug 9, 2026
0f34c36
test(conversion): cover PDF action boundary edge cases
seonghobae Aug 9, 2026
8fdbf3b
test(conversion): reject unsafe PDF URI action schemes
seonghobae Aug 9, 2026
e5680a0
fix(conversion): validate URI annotation schemes
seonghobae Aug 9, 2026
370830d
test(conversion): reject malformed annotation containers
seonghobae Aug 9, 2026
778f3c7
fix(conversion): fail closed on malformed annotations
seonghobae Aug 9, 2026
47ae88e
test(conversion): reject malformed document names
seonghobae Aug 9, 2026
6c6c6ef
fix(conversion): fail closed on malformed document names
seonghobae Aug 9, 2026
2b355d0
test(conversion): reject malformed annotation entries
seonghobae Aug 9, 2026
9882fa2
fix(conversion): fail closed on malformed annotation entries
seonghobae Aug 9, 2026
17f77ab
test(conversion): reject automatic GoTo additional actions
seonghobae Aug 9, 2026
3f4ec7a
test(conversion): preserve empty additional-action dictionaries
seonghobae Aug 9, 2026
be9dfb1
fix(conversion): fail closed on automatic PDF actions
seonghobae Aug 9, 2026
5e40b3d
test(conversion): align automatic action policy with PDF triggers
seonghobae Aug 9, 2026
d4bb850
test(conversion): require source container preflight
seonghobae Aug 9, 2026
11844d3
feat(conversion): validate Office source container signatures
seonghobae Aug 9, 2026
443cf11
fix(conversion): gate providers on source container preflight
seonghobae Aug 9, 2026
ac92f8a
test(conversion): add signature-qualified Office source fixtures
seonghobae Aug 9, 2026
0c47f26
test(conversion): qualify action-policy source fixture
seonghobae Aug 9, 2026
7d93165
test(conversion): qualify active-content source fixture
seonghobae Aug 9, 2026
4b016eb
test(conversion): qualify adapter-identity source fixture
seonghobae Aug 9, 2026
fe6bd39
test(conversion): qualify provenance source fixtures
seonghobae Aug 9, 2026
40b5f75
test(conversion): qualify output-limit source fixture
seonghobae Aug 9, 2026
1bdedc0
test(conversion): qualify page-limit source fixture
seonghobae Aug 9, 2026
0b2e3e9
test(conversion): qualify PDF-validation source fixture
seonghobae Aug 9, 2026
8a2ec3b
test(conversion): qualify URI-policy source fixture
seonghobae Aug 9, 2026
45eee35
test(conversion): qualify action-classification source fixture
seonghobae Aug 9, 2026
c39db6e
test(conversion): qualify binding source fixtures
seonghobae Aug 9, 2026
bc3cc46
test(conversion): qualify deterministic adapter fixture source
seonghobae Aug 9, 2026
1813cac
test(conversion): cover truncated source signature
seonghobae Aug 9, 2026
3ba58bf
test(conversion): require bounded ZIP central-directory framing
seonghobae Aug 9, 2026
3b0281e
fix(conversion): require bounded ZIP framing before provider
seonghobae Aug 9, 2026
c5a3027
test(conversion): frame ZIP-family source fixtures
seonghobae Aug 9, 2026
7113c32
test(conversion): exhaust ZIP framing failure branches
seonghobae Aug 9, 2026
24a5163
refactor(conversion): remove unreachable negative ZIP offset branch
seonghobae Aug 9, 2026
70612ed
test(conversion): reject encrypted and inconsistent ZIP entries
seonghobae Aug 9, 2026
f245c83
fix(conversion): validate ZIP central-directory entries
seonghobae Aug 9, 2026
e83a29e
test(conversion): emit complete central-directory fixture records
seonghobae Aug 9, 2026
38ff39c
test(conversion): use complete central-directory framing fixtures
seonghobae Aug 9, 2026
5292c67
test(conversion): reject unsafe ZIP entry paths
seonghobae Aug 9, 2026
d285b4d
fix(conversion): reject unsafe ZIP entry paths
seonghobae Aug 10, 2026
ac88b3e
test(conversion): add safe ZIP fixture entry name
seonghobae Aug 10, 2026
81ef4d2
test(conversion): qualify shared ZIP fixture paths
seonghobae Aug 10, 2026
18ccc3f
test(conversion): qualify central-directory fixtures
seonghobae Aug 10, 2026
8a3ed99
test(conversion): require local-central ZIP name consistency
seonghobae Aug 10, 2026
387b35f
fix(conversion): bind ZIP local and central entry names
seonghobae Aug 10, 2026
9b35e82
test(conversion): qualify local ZIP header fixture
seonghobae Aug 10, 2026
4369d77
test(conversion): qualify shared ZIP local headers
seonghobae Aug 10, 2026
28c7027
test(conversion): qualify central policy local headers
seonghobae Aug 10, 2026
f693a54
test(conversion): reject local-header encryption mismatch
seonghobae Aug 10, 2026
e1b720f
fix(conversion): reject encrypted ZIP local headers
seonghobae Aug 10, 2026
dd3bbf2
test(conversion): reject local-central compression mismatch
seonghobae Aug 10, 2026
48596e9
fix(conversion): bind ZIP compression metadata
seonghobae Aug 10, 2026
8352eb7
test(conversion): reject unsupported ZIP compression methods
seonghobae Aug 10, 2026
3a20318
fix(conversion): bound ZIP compression methods
seonghobae Aug 10, 2026
83ec6f7
deps(deps): bump com.github.junrar:junrar from 7.6.0 to 8.1.0 (#311)
dependabot[bot] Aug 10, 2026
9adf162
test(conversion): reject fixture fidelity overclaim
seonghobae Aug 10, 2026
8a9b1cd
docs(conversion): stop treating fixture replay as fidelity evidence
seonghobae Aug 10, 2026
b2aa85d
test(conversion): reject impossible ZIP compressed spans
seonghobae Aug 10, 2026
89b201e
fix(conversion): reject impossible ZIP compressed spans
seonghobae Aug 10, 2026
0aea85b
test(conversion): reject inconsistent stored ZIP sizes
seonghobae Aug 10, 2026
31703f5
fix(conversion): reject inconsistent stored ZIP sizes
seonghobae Aug 10, 2026
e5701dc
test(conversion): reject local ZIP size metadata drift
seonghobae Aug 10, 2026
4e006cc
fix(conversion): reject local ZIP size metadata drift
seonghobae Aug 10, 2026
d054356
test(conversion): preserve compressed-span fixture intent
seonghobae Aug 10, 2026
bb1cd45
test(conversion): reject ZIP data-descriptor flag drift
seonghobae Aug 10, 2026
f002e3b
fix(conversion): reject ZIP data-descriptor flag drift
seonghobae Aug 10, 2026
807312c
test(conversion): reject local ZIP CRC metadata drift
seonghobae Aug 10, 2026
1c42938
fix(conversion): reject local ZIP CRC metadata drift
seonghobae Aug 10, 2026
e1c6ba1
test(conversion): require ODF package manifest
seonghobae Aug 10, 2026
d569365
fix(conversion): require ODF package manifest
seonghobae Aug 10, 2026
d2d1bd9
test(conversion): require ODF mimetype first-entry placement
seonghobae Aug 10, 2026
6f979ff
fix(conversion): enforce ODF mimetype first-entry placement
seonghobae Aug 10, 2026
f792687
test(conversion): reject compressed ODF mimetype entry
seonghobae Aug 10, 2026
a4bad56
fix(conversion): require stored ODF mimetype entry
seonghobae Aug 10, 2026
8c886e0
test(conversion): reject ODF mimetype local extra field
seonghobae Aug 10, 2026
6daacad
fix(conversion): reject ODF mimetype local extra field
seonghobae Aug 10, 2026
ee88961
test(conversion): reject mismatched ODF mimetype payload
seonghobae Aug 10, 2026
a5e92fa
fix(conversion): validate ODF mimetype against declared format
seonghobae Aug 10, 2026
5867750
test(conversion): reject unexpected ODF META-INF entries
seonghobae Aug 10, 2026
2d52079
fix(conversion): reject unexpected ODF META-INF entries
seonghobae Aug 10, 2026
4b6419f
test(conversion): reject duplicate ZIP entry names
seonghobae Aug 10, 2026
319a73e
fix(conversion): reject duplicate ZIP entry names
seonghobae Aug 10, 2026
1a18b49
test(conversion): reject ODF manifest media-type mismatch
seonghobae Aug 10, 2026
9f7afd2
feat(conversion): validate ODF manifest media type
seonghobae Aug 10, 2026
1679774
feat(conversion): enforce ODF manifest semantics before provider
seonghobae Aug 10, 2026
fae8097
test(conversion): keep ODF META-INF fixture structurally valid
seonghobae Aug 10, 2026
b8b81d5
test(conversion): require ODF manifest entry coverage
seonghobae Aug 10, 2026
9f06eb5
feat(conversion): bind ODF manifest to package inventory
seonghobae Aug 10, 2026
d96a367
test(conversion): require ODF 1.4 manifest version
seonghobae Aug 10, 2026
914d168
fix(conversion): enforce ODF 1.4 manifest version
seonghobae Aug 10, 2026
466a5ed
test(conversion): require ODF manifest file entries
seonghobae Aug 10, 2026
a5c8671
fix(conversion): require ODF manifest file entry
seonghobae Aug 10, 2026
9b7baaa
test(conversion): keep ODF META-INF fixtures schema-valid
seonghobae Aug 10, 2026
852c2e1
test(conversion): preserve ODF inventory failure boundary
seonghobae Aug 10, 2026
55d7ae8
fix(security): harden audit pseudonymization and refresh Netty eviden…
seonghobae Aug 10, 2026
6449186
test(security): reject non-authoritative web URI actions
seonghobae Aug 10, 2026
d2679ce
fix(security): require authoritative web URI targets
seonghobae Aug 10, 2026
6681b37
Merge d2679ce7aca59fda44d3b685af0b0542946916a0 into 55d7ae8647208e301…
seonghobae Aug 10, 2026
f12a16c
test(conversion): cover Office contract value boundaries
seonghobae Aug 10, 2026
15bf2b8
test(conversion): cover unavailable digest provider
seonghobae Aug 10, 2026
6106c54
test(conversion): cover PDF action boundary branches
seonghobae Aug 10, 2026
997ee71
test(conversion): cover hostile ODF manifest boundaries
seonghobae Aug 10, 2026
aeae17f
test(conversion): exercise real DTD payload
seonghobae Aug 10, 2026
dd7638e
test(conversion): cover ZIP container authority branches
seonghobae Aug 10, 2026
224c204
test(fuzz): probe hostile Office container boundaries
seonghobae Aug 10, 2026
79ef010
test(fuzz): use public Office request authority contract
seonghobae Aug 10, 2026
37f8899
fix(test): align ODF META-INF rejection contract
seonghobae Aug 10, 2026
42b89a5
test(conversion): cover ODF manifest boundary branches
seonghobae Aug 10, 2026
be96e67
refactor(conversion): remove unreachable ODF preflight branches
seonghobae Aug 10, 2026
e4c9ed0
test(conversion): cover residual Office preflight guards
seonghobae Aug 11, 2026
965e324
test(conversion): align ODF mimetype failure contract
seonghobae Aug 11, 2026
96ae69b
test(conversion): close residual ZIP path coverage
seonghobae Aug 11, 2026
f3ab4ea
test(conversion): cover upper punctuation path branch
seonghobae Aug 11, 2026
c4e2979
docs(conversion): document PDF action depth limit
seonghobae Aug 11, 2026
99097bb
docs(conversion): document typed failure authority
seonghobae Aug 11, 2026
12f1b18
test(security): reject impossible empty Deflate expansion
seonghobae Aug 11, 2026
3d0d1da
fix(security): reject impossible empty Deflate expansion
seonghobae Aug 11, 2026
7efc32d
test(conversion): cover local uncompressed size mismatch
seonghobae Aug 11, 2026
2abf9aa
test(conversion): reject VBA payload before provider
seonghobae Aug 11, 2026
42ee91b
fix(conversion): reject VBA project parts before provider
seonghobae Aug 11, 2026
4048ec1
test(conversion): reject embedded OOXML binary parts
seonghobae Aug 11, 2026
2fbdef2
fix(conversion): reject embedded OOXML active content
seonghobae Aug 11, 2026
2818371
test(conversion): reject external Office link parts
seonghobae Aug 11, 2026
57f13ce
fix(conversion): reject external Office link parts
seonghobae Aug 11, 2026
693ffcb
test(conversion): reject OOXML ActiveX parts
seonghobae Aug 11, 2026
c8b1429
fix(conversion): reject OOXML ActiveX parts
seonghobae Aug 11, 2026
6339d54
test(conversion): reject case-equivalent OPC parts
seonghobae Aug 11, 2026
f3a8fdf
fix(conversion): reject case-equivalent OPC parts
seonghobae Aug 11, 2026
ed206aa
test(conversion): reject nonconforming OPC part paths
seonghobae Aug 11, 2026
c51d295
fix(conversion): reject nonconforming OPC part paths
seonghobae Aug 11, 2026
f394357
test(conversion): preserve ODF META-INF coverage
seonghobae Aug 11, 2026
93c1112
refactor(conversion): remove unreachable fragment guard
seonghobae Aug 11, 2026
8cfb3e9
test(conversion): reject OPC segments ending in dot
seonghobae Aug 11, 2026
14b49b3
fix(conversion): reject OPC segments ending in dot
seonghobae Aug 11, 2026
b093fdf
refactor(conversion): keep OPC path checks coverable
seonghobae Aug 11, 2026
54cec24
test(conversion): reject external OOXML relationships
seonghobae Aug 11, 2026
d1f0361
fix(conversion): reject external OOXML relationships
seonghobae Aug 11, 2026
7c748e6
test(conversion): cover root OOXML relationships
seonghobae Aug 11, 2026
6dd0e19
test(conversion): cover malformed OOXML relationship framing
seonghobae Aug 11, 2026
92df109
fix(conversion): cover malformed OOXML relationship framing
seonghobae Aug 11, 2026
7cf4941
test(security): reject renamed VBA content type
seonghobae Aug 12, 2026
2783f98
fix(security): inspect OOXML content-type authority
seonghobae Aug 12, 2026
503dfd0
test(security): cover OOXML content-type boundary
seonghobae Aug 12, 2026
95df57a
docs(security): describe OOXML content-type preflight
seonghobae Aug 12, 2026
84a265e
fix(test): preserve OOXML malformed failure contract
seonghobae Aug 12, 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
87 changes: 83 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
# Every pull request target, including immutable stack branches, receives the
# same exact-head, synthetic-merge, and buyer-readiness acceptance evidence.
pull_request: {}

permissions:
contents: read
Expand All @@ -17,14 +18,87 @@ 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
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
ref: ${{ github.sha }}
- 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 +107,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
45 changes: 32 additions & 13 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,47 @@
## [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

- `GET /api/v1/convert/jobs/{jobId}/download`가 리소스 조회 전에 전용 `artifact:read` 권한을 검증하고, PDF 저장소 접근 전에 작업의 tenant 소유권을 확인하도록 강화했습니다. `job:read`만으로는 문서 바이트를 읽을 수 없으며, 인증 누락·권한 누락·교차 tenant UUID 접근은 각각 fail closed 처리되고 교차 tenant 요청은 리소스 존재를 숨기는 `404`를 반환합니다.
- 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 +57,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 +70,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을 손상시키지 않고 안전하게 복원되도록 수정
Loading
Loading