Skip to content

feat: ingest DiskSage metadata catalog batches - #59

Open
seonghobae wants to merge 7 commits into
mainfrom
feat/disksage-catalog-ingestion
Open

feat: ingest DiskSage metadata catalog batches#59
seonghobae wants to merge 7 commits into
mainfrom
feat/disksage-catalog-ingestion

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a strict v1 adapter for DiskSage disksage.file-catalog-candidate-batch
  • validate embedded-metadata-first production-time lineage and reject path-bearing/unknown fields
  • upsert only path-free file_candidate/catalog_batch graph nodes and cataloged_in edges; no file or provider mutation
  • require the existing admin graph-write policy and document the integration

Evidence

  • Exact head: 113d7c434ecc82ec1c9f95060d587deb1b1b4bcd against main@e48aa13c4af7a4875d4b53e6a60b50405c265a2f.
  • PYTHONPATH=src python -m pytest -q -> 293 passed, 8 integration tests skipped without Postgres.
  • Focused DiskSage adapter tests: 6/6 passed.
  • Exact-head Tests, fuzz, Security Scan, and SAST Semgrep are terminal-success.
  • ruff check src/sdp/disksage_catalog.py src/sdp/api.py tests/test_disksage_catalog.py passed on the preceding functional head; the privacy-only successor changes the validator and its regression test.
  • Cross-repo smoke used the live DiskSage planner output for 251210_1631.m4a and returned HTTP 200; production source remained embedded:ffprobe:comment-date.
  • GraphRAG grounding is already attached in docs/papers/README.md; this change uses the existing property-graph lineage surface.

Privacy boundary repair

  • RED evidence showed that file:///Users/... and Linux /home/... values passed the original absolute-path detector.
  • The exact head rejects file-URI schemes and Linux home paths before graph persistence, while retaining the existing macOS, Windows, UNC, NUL, and strict-field protections.

Safety

  • The request contract has no local path fields and rejects absolute path-like metadata values.
  • This endpoint never copies, deletes, evicts, or grants cloud access.
  • DiskSage/Naruon cloud-write approval and provider receipt gates remain separate.
  • Merge still requires an exact-current-head qualifying independent formal approval; predecessor review evidence does not transfer.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Caution

Review failed

An error occurred during the review process. Please try again later.


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.

@seonghobae
seonghobae force-pushed the feat/disksage-catalog-ingestion branch from b05da1b to 013a69d Compare August 11, 2026 12:26
@seonghobae
seonghobae force-pushed the feat/disksage-catalog-ingestion branch from 013a69d to e87b0c0 Compare August 11, 2026 12:28

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Please perform an independent formal review of exact head 16fee18895e01f643066168c260f1b291aa68135. Tests, fuzz, Security Scan, and SAST Semgrep are all terminal-success on this SHA; CodeRabbit was rate-limited and produced no review. Validate the path-free DiskSage catalog schema boundary, production-time precedence enforcement, RBAC on ingestion, deterministic graph identity/upserts, privacy rejection tests, and dependency-lock consistency. Anchor any formal result to this exact head.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Please perform an independent formal review of exact current head 113d7c434ecc82ec1c9f95060d587deb1b1b4bcd. This head closes a reproduced privacy gap: file:///Users/... and Linux /home/... paths previously passed the path-free validator; the new regression failed before the fix and now passes. Local validation: the focused file has 6/6 passing tests and the complete suite has 293 passed with 8 integration skips. Exact-head Tests, fuzz, Security Scan, and SAST Semgrep are all terminal-success. Revalidate the path-free DiskSage boundary and anchor the formal result only to this SHA.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact current head 113d7c434ecc82ec1c9f95060d587deb1b1b4bcd against live base snapshot e48aa13c4af7a4875d4b53e6a60b50405c265a2f. Revalidate the path-free DiskSage boundary, including the reproduced file:///Users/... and Linux /home/... rejection fix. Tests, fuzz, Security Scan, and SAST are terminal-success on this unchanged SHA; local focused privacy tests are 6/6 and the complete suite is 293 passed with 8 integration skips. Anchor all findings and any formal result to this head.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

requested_head='113d7c434ecc82ec1c9f95060d587deb1b1b4bcd'
requested_base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'

echo '== checked-out HEAD =='
git rev-parse HEAD
echo '== requested commits =='
git cat-file -t "$requested_head"
git cat-file -t "$requested_base"
echo '== ancestry and merge-base =='
git merge-base "$requested_base" "$requested_head"
git merge-base --is-ancestor "$requested_base" "$requested_head" && echo 'base-is-ancestor=yes'
echo '== changed files =='
git diff --name-status "$requested_base" "$requested_head"
echo '== diff stat =='
git diff --stat "$requested_base" "$requested_head"

Length of output: 1818


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'
head='113d7c434ecc82ec1c9f95060d587deb1b1b4bcd'

echo '== adapter outline =='
ast-grep outline src/sdp/disksage_catalog.py --items all --view expanded
echo '== API outline: DiskSage candidates =='
ast-grep outline src/sdp/api.py --items all --match 'disksage|catalog|graph' --view expanded || true
echo '== test outline =='
ast-grep outline tests/test_disksage_catalog.py --items all --view expanded
echo '== adapter diff =='
git diff --unified=80 "$base" "$head" -- src/sdp/disksage_catalog.py
echo '== API diff =='
git diff --unified=50 "$base" "$head" -- src/sdp/api.py
echo '== test diff =='
git diff --unified=40 "$base" "$head" -- tests/test_disksage_catalog.py
echo '== declared dependency diffs =='
git diff --unified=8 "$base" "$head" -- pyproject.toml requirements-dev.txt requirements-test.in requirements-test.txt requirements.txt

Length of output: 61208


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== exact relevant source lines =='
nl -ba src/sdp/disksage_catalog.py | sed -n '38,70p;120,220p;230,315p'
nl -ba src/sdp/api.py | sed -n '685,765p'

echo '== graph store maps =='
fd -t f 'graph_store|authz|policy' src/sdp -x sh -c '
  echo "----- $1 -----"
  ast-grep outline "$1" --items all --view expanded
' sh {}

echo '== graph upsert implementations and policy evaluation =='
rg -n -A28 -B8 --glob '*.py' \
  'def upsert_node\(|def upsert_edge\(|def evaluate\(|def _authorize_graph_write\(' src/sdp

echo '== DiskSage references and privacy-related tests =='
rg -n -A8 -B4 --glob '*.py' \
  'disksage|_contains_local_path|_LOCAL_PATH_RE|file:///|/home/|/etc/|/tmp/' src tests

echo '== documentation and dependency declarations =='
git diff --unified=30 e48aa13c4af7a4875d4b53e6a60b50405c265a2f 113d7c434ecc82ec1c9f95060d587deb1b1b4bcd -- README.md docs/implementation-compliance.md
printf '\n-- cryptography pins --\n'
rg -n -A3 -B2 '^cryptography|^PyJWT' pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt

Length of output: 1475


🏁 Script executed:

#!/bin/bash
set -euo pipefail

numbered_slice() {
  file="$1"
  range="$2"
  sed -n "${range}=" "$file" | paste -d' ' - <(sed -n "${range}p" "$file")
}

echo '== exact relevant source lines =='
numbered_slice src/sdp/disksage_catalog.py '38,70p'
numbered_slice src/sdp/disksage_catalog.py '120,220p'
numbered_slice src/sdp/disksage_catalog.py '230,315p'
numbered_slice src/sdp/api.py '685,765p'

echo '== candidate graph, authorization, and policy files =='
fd -t f . src/sdp | rg '/(graph_store|authz|policy)(\.py|/)'

echo '== graph upsert implementations and policy evaluation =='
rg -n -A28 -B8 --glob '*.py' \
  'def upsert_node\(|def upsert_edge\(|def evaluate\(|def _authorize_graph_write\(' src/sdp

echo '== DiskSage references and privacy-related tests =='
rg -n -A8 -B4 --glob '*.py' \
  'disksage|_contains_local_path|_LOCAL_PATH_RE|file:///|/home/|/etc/|/tmp/' src tests

echo '== documentation delta =='
git diff --unified=30 e48aa13c4af7a4875d4b53e6a60b50405c265a2f 113d7c434ecc82ec1c9f95060d587deb1b1b4bcd -- README.md docs/implementation-compliance.md

echo '== cryptography and PyJWT pins =='
rg -n -A3 -B2 '^cryptography|^PyJWT' \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt

Length of output: 1754


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== DiskSage validator and ingestion =='
sed -n '38,315p' src/sdp/disksage_catalog.py

echo '== graph write authorization and DiskSage endpoint =='
sed -n '685,765p' src/sdp/api.py

echo '== graph store, authorization, and policy definitions =='
rg -n -A36 -B10 --glob '*.py' \
  'def upsert_node\(|def upsert_edge\(|def evaluate\(|def _authorize_graph_write\(' src/sdp

echo '== DiskSage privacy tests and references =='
rg -n -A10 -B5 --glob '*.py' \
  'disksage|_contains_local_path|_LOCAL_PATH_RE|file:///|/home/|/etc/|/tmp/' src tests

echo '== DiskSage documentation changes =='
git diff --unified=25 e48aa13c4af7a4875d4b53e6a60b50405c265a2f 113d7c434ecc82ec1c9f95060d587deb1b1b4bcd -- README.md docs/implementation-compliance.md

echo '== lock/declaration consistency =='
rg -n -A3 -B2 '^cryptography|^PyJWT' \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt

Length of output: 63588


@seonghobae I reviewed exact head 113d7c434ecc82ec1c9f95060d587deb1b1b4bcd against base e48aa13c4af7a4875d4b53e6a60b50405c265a2f.

Formal result: not qualified.

Blocking finding: generic POSIX absolute paths remain accepted

src/sdp/disksage_catalog.py Line 45 rejects only /Users/, /home/, /private/, and /Volumes/ among POSIX paths. It does not reject generic absolute paths.

For example, this valid schema field passes validation:

{
  "content_context": ["source=/etc/sdp/secret.json"]
}

/etc/sdp/secret.json follows = but does not match any _LOCAL_PATH_RE alternative. The same applies to /tmp/..., /var/..., and other absolute POSIX paths.

The candidate validator at Line 130 therefore accepts the request. The ingestion path then persists content_context in graph-node properties and includes it in graph embedding text at Lines 243-250 and Lines 286-296.

Update the detector to reject any absolute POSIX path token, not only selected home and macOS prefixes. Add regression tests for at least /etc/... and /tmp/... in tests/test_disksage_catalog.py.

The requested privacy repair is otherwise present. The implementation rejects file:///Users/... and /home/..., and Lines 144-154 cover both cases.

I also verified these items:

  • The endpoint uses the existing admin graph-write policy at src/sdp/api.py Line 762.
  • Batch IDs use canonical batch JSON hashes. Candidate IDs use candidate fingerprints.
  • cataloged_in edge upserts use deterministic source and target IDs.
  • The production-time validator rejects a lower-precedence selected source when recognized higher-precedence evidence exists.
  • The dependency declarations and lock files consistently pin cryptography==50.0.0.

You are interacting with an AI system.

@seonghobae
seonghobae enabled auto-merge August 13, 2026 20:05

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please perform an independent formal review of exact current head 113d7c434ecc82ec1c9f95060d587deb1b1b4bcd against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f. Revalidate the path-free DiskSage ingestion boundary, embedded-metadata-first production-time lineage, authorization, deterministic graph identities/upserts, privacy rejection coverage, and dependency-lock consistency. Current exact-head check runs contain no failure, queued, or in-progress conclusion, but skipped jobs are not offered as evidence. Anchor every finding and any formal review only to this SHA.

@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Rate Limit Exceeded

@seonghobae have exceeded the limit for the number of chat messages per hour. Please wait 28 minutes and 40 seconds before sending another message.

CodeRabbit flagged that DiskSage catalog validation only blocked a
selected prefix list. Generic absolute paths such as /etc and /tmp
could still persist in graph properties. Reject any absolute POSIX
token and add regressions for those cases.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
@seonghobae

Copy link
Copy Markdown
Contributor Author

Pushed 82db4f7 on this branch to close the CodeRabbit finding on 113d7c4.

_contains_local_path now rejects any absolute POSIX path token, not only /Users/, /home/, /private/, and /Volumes/. Regressions cover source=/etc/sdp/secret.json and source=/tmp/disksage-preview.m4a in tests/test_disksage_catalog.py. HTTPS context values remain accepted so https://... is not treated as a local path.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact current head 82db4f7571bffcbeb08fcdc5a9b77b5e79384b8f against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f. Revalidate the path-free DiskSage boundary, including the CodeRabbit blocking finding on 113d7c4: generic absolute POSIX tokens such as /etc/... and /tmp/... must be rejected, not only /Users/, /home/, /private/, and /Volumes/. Anchor all findings and any formal result only to this head.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please perform an independent formal review of exact current head 82db4f7571bffcbeb08fcdc5a9b77b5e79384b8f against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f. The previous blocking finding on 113d7c4 is addressed: _LOCAL_PATH_RE now rejects any absolute POSIX path token (/[^/\s]+), not only /Users/, /home/, /private/, and /Volumes/. Regressions in tests/test_disksage_catalog.py cover source=/etc/sdp/secret.json and source=/tmp/disksage-preview.m4a. HTTPS context values remain accepted. Anchor every finding and any formal result only to this SHA.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'
head='82db4f7571bffcbeb08fcdc5a9b77b5e79384b8f'

echo '== Repository and commit identity =='
printf 'checked_out='; git rev-parse HEAD
git cat-file -t "$base"
git cat-file -t "$head"
printf 'merge_base='; git merge-base "$base" "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'

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

echo '== DiskSage adapter outline =='
ast-grep outline src/sdp/disksage_catalog.py --items all --view expanded

echo '== Adapter and test diffs =='
git diff --unified=80 "$base" "$head" -- src/sdp/disksage_catalog.py tests/test_disksage_catalog.py

echo '== API diff and endpoint context =='
git diff --unified=50 "$base" "$head" -- src/sdp/api.py
rg -n -A45 -B20 --glob '*.py' 'disksage|_authorize_graph_write\(' src/sdp/api.py

echo '== Graph upsert and authorization implementations =='
rg -n -A36 -B10 --glob '*.py' \
  'def upsert_node\(|def upsert_edge\(|def evaluate\(|def _authorize_graph_write\(' src/sdp

echo '== DiskSage tests and privacy patterns =='
rg -n -A18 -B8 --glob '*.py' \
  '_LOCAL_PATH_RE|_contains_local_path|file:///|/home/|/etc/|/tmp/|https://' \
  src/sdp/disksage_catalog.py tests/test_disksage_catalog.py

echo '== Dependency declaration and lock diffs =='
git diff --unified=12 "$base" "$head" -- \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt

Length of output: 101647


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'
head='82db4f7571bffcbeb08fcdc5a9b77b5e79384b8f'

echo '== Role resolution and authentication surfaces =='
fd -t f . src/sdp | rg '/(authz|policy|api)(\.py|/)'
rg -n -A35 -B8 --glob '*.py' \
  'def has_role\(|def _is_admin\(|def authenticate|Authorization|Bearer|actor:|subject=' \
  src/sdp

echo '== Comparable mutation endpoint authorization =='
rg -n -A20 -B8 --glob '*.py' \
  '`@app`\.(post|patch|put|delete)\(|_authorize_graph_write\(|evaluate\(subject=.*action="(create|publish|patch|deprecate)"' \
  src/sdp/api.py

echo '== Full DiskSage documentation delta =='
git diff --unified=70 "$base" "$head" -- README.md docs/implementation-compliance.md

echo '== Direct dependency pins in manifests and lock package headers =='
for f in pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt; do
  echo "----- $f -----"
  rg -n -A2 -B2 '^(cryptography|PyJWT|fastapi|pydantic|psycopg|uvicorn)==|^cryptography==' "$f" || true
done

echo '== Additional path-boundary test coverage =='
rg -n -A10 -B5 --glob '*.py' \
  'path-bearing|local.path|absolute.path|file.uri|relative_path|content_context|metadata_evidence' \
  tests src/sdp/disksage_catalog.py

echo '== Exact source line locations for the candidate finding =='
nl -ba src/sdp/disksage_catalog.py | sed -n '44,70p;136,178p;240,315p'

Length of output: 117325


@seonghobae I reviewed exact head 82db4f7571bffcbeb08fcdc5a9b77b5e79384b8f against base e48aa13c4af7a4875d4b53e6a60b50405c265a2f.

Formal result: not qualified.

Blocking finding 1: The path-free boundary still accepts punctuation-delimited POSIX paths

src/sdp/disksage_catalog.py Line 48 detects an absolute POSIX path only at the start of a string or after whitespace, =, or :.

This accepted value contains a local absolute path:

{
  "content_context": ["recording (/etc/sdp/secret.json)"]
}

The character before /etc is (. It does not match (?:^|[\s=:]). The validator at Line 140 therefore accepts the candidate. The adapter then persists content_context in graph-node properties and embedding text.

The /etc/... and /tmp/... regressions fix the previous case. They do not cover this remaining form of the same privacy escape.

Reject absolute POSIX paths after other token delimiters such as (, [, {, ", ', and ,. Keep the explicit HTTPS acceptance test. Add endpoint-level regressions for punctuation-delimited paths.

Blocking finding 2: The ingestion RBAC guard trusts a caller-controlled actor

DiskSageCatalogRequest.actor at src/sdp/disksage_catalog.py Line 211 is supplied in the request JSON. The endpoint passes that value directly to _authorize_graph_write at src/sdp/api.py Line 762.

src/sdp/authz.py maps the literal value "admin" to administrative roles. The endpoint does not invoke the available OIDC token-verification path or otherwise bind actor to an authenticated request identity.

An unauthenticated caller can submit:

{
  "actor": "admin",
  "catalog": { "...": "valid DiskSage batch" }
}

The policy then authorizes the graph write. The existing graph-write endpoints use the same model, but this means the new endpoint does not enforce the claimed admin-only ingestion boundary.

Derive the actor from verified request authentication. Do not accept the authorization subject from the request body. Add tests that reject a request with actor: "admin" when it has no valid authenticated principal.

Verified items

  • The specific prior gap for source=/etc/... and source=/tmp/... is covered by new tests.
  • file:///..., /home/..., Windows drive paths, UNC paths, NUL bytes, and unknown schema fields are rejected by the adapter.
  • The embedded-metadata-first precedence validator rejects a lower-precedence selected source when recognized higher-precedence evidence exists.
  • Batch IDs, candidate IDs, and cataloged_in edges are deterministic. The graph-store implementations perform keyed upserts.
  • cryptography==50.0.0 is consistent in pyproject.toml, requirements-test.in, and the inspected lock files.

I did not execute repository tests because the review sandbox prohibits repository execution.

You are interacting with an AI system.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Please perform an independent formal review of exact current head 82db4f7571bffcbeb08fcdc5a9b77b5e79384b8f against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f. This head closes the CodeRabbit blocking finding on 113d7c4: generic absolute POSIX tokens such as /etc/sdp/secret.json and /tmp/... are now rejected, not only /Users/, /home/, /private/, and /Volumes/. Local validation: focused DiskSage tests 9/9 and complete suite 265 passed with 8 integration skips. Anchor any formal result only to this SHA.

CodeRabbit found that /etc and /tmp still persisted when wrapped in
parentheses or other punctuation, because the detector only looked
after start, whitespace, =, or :. Treat (, [, {, quotes, and commas
as delimiters and add endpoint regressions. HTTPS context stays valid.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact current head b74cf33dbfc8dde87c3f79351528313e2ca2978b against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f. The 82db4f7 punctuation gap is closed: absolute POSIX tokens are now rejected after (, [, {, quotes, and commas as well as start/whitespace/=/:. Endpoint regressions cover recording (/etc/sdp/secret.json) and related forms. HTTPS context remains accepted. Anchor every finding and any formal result only to this head.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'
head='b74cf33dbfc8dde87c3f79351528313e2ca2978b'

echo '== Commit identity and ancestry =='
printf 'checked_out='; git rev-parse HEAD
printf 'base_type='; git cat-file -t "$base"
printf 'head_type='; git cat-file -t "$head"
printf 'merge_base='; git merge-base "$base" "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'

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

echo '== DiskSage adapter outline =='
ast-grep outline src/sdp/disksage_catalog.py --items all --view expanded

echo '== DiskSage adapter and test diff =='
git diff --unified=100 "$base" "$head" -- \
  src/sdp/disksage_catalog.py tests/test_disksage_catalog.py

echo '== Endpoint and authorization context =='
rg -n -A55 -B20 --glob '*.py' \
  'disksage|DiskSageCatalogRequest|_authorize_graph_write\(|def has_role\(|def evaluate\(' \
  src/sdp/api.py src/sdp/authz.py

echo '== Graph identity and upsert implementations =='
rg -n -A40 -B10 --glob '*.py' \
  'def (canonical|candidate|batch).*id|def upsert_node\(|def upsert_edge\(|cataloged_in' \
  src/sdp

echo '== Privacy tests and exact source locations =='
rg -n -A24 -B8 --glob '*.py' \
  '_LOCAL_PATH_RE|_contains_local_path|file:///|/etc/|/tmp/|recording \(|https://' \
  src/sdp/disksage_catalog.py tests/test_disksage_catalog.py

echo '== Documentation and dependency consistency =='
git diff --unified=40 "$base" "$head" -- README.md docs/implementation-compliance.md \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt
rg -n -A3 -B2 '^(cryptography|PyJWT|fastapi|pydantic|psycopg|uvicorn)==|^cryptography==' \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt

Length of output: 135326


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== API middleware and authentication routes =='
sed -n '105,175p' src/sdp/api.py
rg -n -A60 -B15 --glob '*.py' \
  'oidc|verify.*token|Authorization|HTTPBearer|OAuth2|authenticate|resolve_oidc_actor_context' \
  src/sdp

echo '== Request models that supply graph authorization subjects =='
rg -n -A20 -B8 --glob '*.py' \
  'class (DiskSageCatalogRequest|GraphNodeRequest|GraphEdgeRequest|OntologyConceptRequest)|actor:' \
  src/sdp/domain.py src/sdp/disksage_catalog.py src/sdp/api.py

echo '== Policy decision implementation and built-in subjects =='
rg -n -A70 -B12 --glob '*.py' \
  'def evaluate\(|_SUBJECTS\s*=|ActorContext\(subject="admin"|action == "create"|action.*create' \
  src/sdp/policy.py src/sdp/authz.py

echo '== Delimiter-boundary coverage and detector expression =='
nl -ba src/sdp/disksage_catalog.py | sed -n '44,72p;136,146p;210,216p'
nl -ba tests/test_disksage_catalog.py | sed -n '95,220p'

Length of output: 47582


@seonghobae I reviewed exact head b74cf33dbfc8dde87c3f79351528313e2ca2978b against base e48aa13c4af7a4875d4b53e6a60b50405c265a2f.

Formal result: not qualified.

Blocking finding 1: The path-free boundary still accepts absolute paths after unlisted delimiters

src/sdp/disksage_catalog.py Line 48 uses a fixed delimiter list:

_PATH_TOKEN_PREFIX = r"(?:^|[\s=:({\[\"',])"

The new tests correctly cover (, [, {, quotes, and commas. However, the following valid content_context value still bypasses _LOCAL_PATH_RE:

{
  "content_context": ["recording;/etc/sdp/secret.json"]
}

The preceding character is ;, which is not in the delimiter class. The validator at Line 142 accepts the candidate. The ingestion path then persists content_context and uses it as embedding text.

The same bypass applies after other unlisted delimiters, such as >, |, and backticks. File URIs and Windows paths have the same delimiter limitation.

Reject absolute local paths independently of a fixed prefix delimiter list, or define a complete token-boundary rule. Add endpoint regressions for at least:

recording;/etc/sdp/secret.json
recording|/tmp/disksage-preview.m4a

Blocking finding 2: The DiskSage endpoint does not bind actor to an authenticated principal

DiskSageCatalogRequest.actor at src/sdp/disksage_catalog.py Line 213 comes from request JSON. src/sdp/api.py Line 762 passes it directly to _authorize_graph_write.

src/sdp/authz.py Line 16 maps the literal "admin" to administrator roles. The API middleware records observability data only. It does not verify credentials or establish a request principal. The available OIDC verification path is a separate /enterprise/auth/oidc-verify endpoint. The DiskSage endpoint does not invoke it.

Therefore, an unauthenticated caller can submit a valid catalog with:

{
  "actor": "admin",
  "catalog": { "...": "valid DiskSage batch" }
}

The policy allows the graph write. The existing lower-level graph endpoints use the same pattern, but this endpoint cannot claim admin-only ingestion authorization.

Derive the authorization subject from verified request authentication. Do not accept actor from the ingestion request body. Add tests that reject actor: "admin" without a valid authenticated principal.

Verified items

  • The requested head and base relationship are correct.
  • The new detector rejects the previously reported /etc/... and /tmp/... forms.
  • The new endpoint tests reject the stated parenthesis, bracket, brace, quote, and comma forms.
  • The HTTPS regression remains present.
  • Strict models reject unknown fields.
  • The lineage validator enforces embedded-metadata precedence over recognized lower-precedence sources.
  • Batch IDs, candidate IDs, and cataloged_in edge identifiers are deterministic.
  • The graph stores use keyed node and edge upserts.
  • cryptography==50.0.0 is consistent across the project dependency declaration and inspected lock files.

I performed static inspection only. I did not execute repository code or tests in this sandbox.

You are interacting with an AI system.

CodeRabbit showed that a fixed prefix class still accepted
recording;/etc/... and recording|/tmp/.... Strip http(s) URLs first,
then reject any absolute POSIX token after a non-alphanumeric
boundary so new punctuation cannot reopen the leak.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please perform an independent formal review of exact current head 75f4aed526af57e114228f8c03463bdcd36596a5 against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f.

Path-free boundary: _contains_local_path no longer uses a delimiter allowlist. It rejects file: URIs, strips http(s) URLs, then rejects any absolute POSIX token after a non-alphanumeric boundary. Endpoint regressions include source=/etc/sdp/secret.json, source=/tmp/disksage-preview.m4a, recording (/etc/sdp/secret.json), recording;/etc/sdp/secret.json, and recording|/tmp/disksage-preview.m4a. HTTPS context remains accepted.

The request-body actor field is the existing graph-write contract shared with /graph/nodes and /graph/edges; changing it is out of scope for this DiskSage path-boundary PR.

Anchor every finding and any formal result only to this SHA.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Please perform an independent formal review of exact current head 75f4aed526af57e114228f8c03463bdcd36596a5 against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f. This head closes the remaining path-token delimiter-allowlist gap: recording;/etc/sdp/secret.json and recording|/tmp/disksage-preview.m4a are rejected without a fixed punctuation list. HTTPS context remains accepted. Anchor any formal result only to this SHA.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Please perform an independent formal review of exact current head b74cf33dbfc8dde87c3f79351528313e2ca2978b against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f. This head closes the punctuation-delimited POSIX path gap on 82db4f7: absolute POSIX tokens are rejected after (, [, {, quotes, and commas as well as start/whitespace/=/:. Endpoint regressions cover recording (/etc/sdp/secret.json) and related forms. HTTPS context remains accepted. Anchor any formal result only to this SHA.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please perform an independent formal review of exact current head b74cf33dbfc8dde87c3f79351528313e2ca2978b against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f. Revalidate the path-free DiskSage boundary after the punctuation-delimiter repair, including parenthesis/bracket/brace/quote/comma regressions and HTTPS acceptance. Anchor every finding and any formal result only to this head.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'
head='b74cf33dbfc8dde87c3f79351528313e2ca2978b'

echo '== commit identity and ancestry =='
printf 'checked_out='; git rev-parse HEAD
printf 'base_type='; git cat-file -t "$base"
printf 'head_type='; git cat-file -t "$head"
printf 'merge_base='; git merge-base "$base" "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'

echo '== changed files =='
git diff --name-status "$base" "$head"

echo '== DiskSage adapter outline =='
ast-grep outline src/sdp/disksage_catalog.py --items all --view expanded

echo '== adapter and test diff =='
git diff --unified=100 "$base" "$head" -- \
  src/sdp/disksage_catalog.py tests/test_disksage_catalog.py

echo '== endpoint and authorization context =='
rg -n -A55 -B20 --glob '*.py' \
  'disksage|DiskSageCatalogRequest|_authorize_graph_write\(|def has_role\(|def evaluate\(' \
  src/sdp/api.py src/sdp/authz.py src/sdp/policy.py

echo '== graph identity and upsert implementations =='
rg -n -A40 -B10 --glob '*.py' \
  'def (canonical|candidate|batch).*id|def upsert_node\(|def upsert_edge\(|cataloged_in' \
  src/sdp

echo '== privacy patterns and tests =='
rg -n -A24 -B8 --glob '*.py' \
  '_LOCAL_PATH_RE|_contains_local_path|file:///|/etc/|/tmp/|recording \(|https://' \
  src/sdp/disksage_catalog.py tests/test_disksage_catalog.py

echo '== dependency declarations and locks =='
git diff --unified=30 "$base" "$head" -- \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt
rg -n -A3 -B2 '^(cryptography|PyJWT|fastapi|pydantic|psycopg|uvicorn)==|^cryptography==' \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt

Length of output: 125362


@seonghobae I reviewed exact head b74cf33dbfc8dde87c3f79351528313e2ca2978b against base e48aa13c4af7a4875d4b53e6a60b50405c265a2f.

Formal result: not qualified.

Blocking finding: The exact b74 path detector still has an incomplete delimiter list

src/sdp/disksage_catalog.py Line 48 in exact head b74cf33dbfc8dde87c3f79351528313e2ca2978b defines:

_PATH_TOKEN_PREFIX = r"(?:^|[\s=:({\[\"',])"

The detector rejects the requested parenthesis, bracket, brace, quote, and comma cases. The tests cover these forms.

However, it does not reject local paths after delimiters outside that class. These accepted values contain absolute local paths:

{
  "content_context": [
    "recording;/etc/sdp/secret.json",
    "recording|/tmp/disksage-preview.m4a"
  ]
}

; and | do not match _PATH_TOKEN_PREFIX. The validator accepts the candidate. ingest_catalog_batch() then stores content_context in node properties and graph embedding text.

Reject absolute POSIX paths without a fixed delimiter allowlist. Add endpoint regressions for semicolon and pipe delimiters.

Verified items

  • The base commit is an ancestor of the requested head.
  • Exact b74 rejects the requested parenthesis, bracket, brace, single-quote, double-quote, and comma path forms.
  • Exact b74 accepts the HTTPS context regression.
  • Strict Pydantic models reject unknown fields.
  • The candidate validator scans nested metadata for local paths, Windows paths, UNC paths, file URIs, and NUL bytes.
  • The production-time validator requires selected evidence and rejects a lower-precedence source when recognized higher-precedence evidence exists.
  • Batch IDs, candidate IDs, and cataloged_in edge endpoints are deterministic.
  • The graph stores implement keyed upserts.
  • cryptography==50.0.0 is consistent across the project declaration and inspected lock files.

The sandbox worktree was checked out at successor commit 75f4aed526af57e114228f8c03463bdcd36596a5. I used the exact Git diff for b74 as evidence. I did not execute repository code or tests.

Thanks for clarifying that actor is the existing shared graph-write contract. I did not include that item in this PR-scoped result.


✏️ Learnings added
Learnt from: seonghobae
URL: https://github.com/ContextualWisdomLab/semantic-data-portal/pull/59

Timestamp: 2026-08-17T18:21:55.934Z
Learning: The DiskSage catalog ingestion endpoint at `src/sdp/api.py` uses the request-body `actor` field because this is the existing graph-write contract shared with `/graph/nodes` and `/graph/edges`. Changing that authorization contract is outside the scope of the DiskSage path-boundary PR.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'
head='75f4aed526af57e114228f8c03463bdcd36596a5'

echo '== Commit identity and ancestry =='
printf 'checked_out='; git rev-parse HEAD
printf 'base_type='; git cat-file -t "$base"
printf 'head_type='; git cat-file -t "$head"
printf 'merge_base='; git merge-base "$base" "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'

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

echo '== DiskSage adapter outline =='
ast-grep outline src/sdp/disksage_catalog.py --items all --view expanded

echo '== Adapter and test changes =='
git diff --unified=100 "$base" "$head" -- \
  src/sdp/disksage_catalog.py tests/test_disksage_catalog.py

echo '== Endpoint and authorization context =='
rg -n -A55 -B20 --glob '*.py' \
  'disksage|DiskSageCatalogRequest|_authorize_graph_write\(|def has_role\(|def evaluate\(' \
  src/sdp/api.py src/sdp/authz.py src/sdp/policy.py

echo '== Graph identity and upsert context =='
rg -n -A42 -B12 --glob '*.py' \
  'def (canonical|candidate|batch).*id|def upsert_node\(|def upsert_edge\(|cataloged_in' \
  src/sdp

echo '== Exact privacy detector and tests =='
nl -ba src/sdp/disksage_catalog.py | sed -n '35,85p;120,185p;200,320p'
nl -ba tests/test_disksage_catalog.py | sed -n '1,280p'

echo '== Documentation and dependency consistency =='
git diff --unified=45 "$base" "$head" -- \
  README.md docs/implementation-compliance.md pyproject.toml requirements.txt \
  requirements-dev.txt requirements-test.in requirements-test.txt
rg -n -A3 -B2 '^(cryptography|PyJWT|fastapi|pydantic|psycopg|uvicorn)==|^cryptography==' \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt

Length of output: 65094


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'
head='75f4aed526af57e114228f8c03463bdcd36596a5'

echo '== API change =='
git diff --unified=70 "$base" "$head" -- src/sdp/api.py

echo '== Remainder of DiskSage tests =='
sed -n '200,300p' tests/test_disksage_catalog.py

echo '== All DiskSage path test assertions =='
rg -n -A8 -B4 --glob '*.py' \
  '_contains_local_path\(|file:|https?://|/[A-Za-z]|\\\\|relative_path|path-bearing' \
  tests/test_disksage_catalog.py src/sdp/disksage_catalog.py

echo '== Request model and graph-write contract comparison =='
rg -n -A24 -B8 --glob '*.py' \
  'class (GraphNodeRequest|GraphEdgeRequest|OntologyConceptRequest)|actor:|def ingest_(graph_node|graph_edge|disksage_catalog)' \
  src/sdp/domain.py src/sdp/disksage_catalog.py src/sdp/api.py

echo '== DiskSage documentation =='
git diff --unified=80 "$base" "$head" -- README.md docs/implementation-compliance.md

echo '== Dependency changes and declared pins =='
git diff --unified=30 "$base" "$head" -- \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt
for f in pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt; do
  echo "----- $f -----"
  grep -nE '^(cryptography|PyJWT|fastapi|pydantic|psycopg|uvicorn)(\[.*\])?([=<>!~].*)?$|^cryptography==' "$f" || true
done

echo '== Graph node and edge constraints =='
rg -n -A22 -B8 --glob '*.py' \
  'CREATE TABLE.*graph_(nodes|edges)|UNIQUE|PRIMARY KEY|ON CONFLICT \(node_id\)|ON CONFLICT \(edge_type, source_id, target_id\)' \
  src/sdp/graph_store.py

Length of output: 94659


@seonghobae I reviewed exact head 75f4aed526af57e114228f8c03463bdcd36596a5 against base e48aa13c4af7a4875d4b53e6a60b50405c265a2f.

Formal result: not qualified.

Blocking finding: The path-free boundary accepts the POSIX root path

src/sdp/disksage_catalog.py Line 52 defines:

_ABSOLUTE_POSIX_RE = re.compile(r"(?<![A-Za-z0-9])/[^/\s]")

The expression requires one non-slash, non-whitespace character after /. It does not match a root path at the end of a string or before whitespace.

These values pass _contains_local_path():

{
  "content_context": ["/"]
}
{
  "content_context": ["source=/ "]
}

Candidate.validate_lineage_evidence() then accepts the candidate and ingestion persists content_context in node properties and graph embedding text.

Reject / as an absolute POSIX path token. Reject it when whitespace follows it. Add endpoint regressions for at least "/" and "source=/ ".

Verified items

  • The reviewed HEAD matches the requested SHA. The requested base is its ancestor.
  • The new non-alphanumeric-boundary rule rejects the prior /etc/... and /tmp/... bypasses after (, [, {, quotes, commas, ;, and |.
  • The HTTPS regression is present.
  • Strict request models reject unknown fields.
  • The lineage validator requires selected evidence and rejects a lower-precedence source when recognized higher-precedence evidence exists.
  • The endpoint uses the existing graph-write policy contract.
  • Batch IDs, candidate IDs, and cataloged_in edge keys are deterministic.
  • Both graph stores use keyed upserts.
  • cryptography==50.0.0 is consistent in the project dependency declaration and inspected lock files.

The request-body actor remains a shared graph-write authorization limitation. This PR does not introduce that limitation. You marked it out of scope. Do you want a follow-up GitHub issue for authenticated-principal binding?

I used static inspection only. I did not execute repository code or tests.

You are interacting with an AI system.

CodeRabbit showed that `/` and `source=/ ` still passed the path-free
detector because it required a non-slash character after `/`. Treat a
trailing or whitespace-followed root as an absolute POSIX token.
HTTPS context remains accepted.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please perform an independent formal review of exact current head 65e4fd770c69192daafe51854eb73eb2f06f0bf4 against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f.

Path-free boundary: _contains_local_path rejects absolute POSIX tokens after any non-alphanumeric boundary and now also rejects a lone root (/, source=/ ). Endpoint regressions include recording;/etc/sdp/secret.json, recording|/tmp/disksage-preview.m4a, /, and source=/ . HTTPS context remains accepted.

The request-body actor field remains the existing graph-write contract shared with /graph/nodes and /graph/edges; changing it is out of scope.

Anchor every finding and any formal result only to this SHA.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Please perform an independent formal review of exact current head 65e4fd770c69192daafe51854eb73eb2f06f0bf4 against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f. This head closes the remaining POSIX-root gap on 75f4aed: / and source=/ are rejected. HTTPS context remains accepted. Anchor any formal result only to this SHA.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'
head='65e4fd770c69192daafe51854eb73eb2f06f0bf4'

echo '== exact identity and ancestry =='
printf 'checked_out='; git rev-parse HEAD
printf 'base_type='; git cat-file -t "$base"
printf 'head_type='; git cat-file -t "$head"
printf 'merge_base='; git merge-base "$base" "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'

echo '== changed paths =='
git diff --name-status "$base" "$head"

echo '== DiskSage adapter outline at requested head =='
git show "$head:src/sdp/disksage_catalog.py" > /tmp/disksage_catalog.py
ast-grep outline /tmp/disksage_catalog.py --items all --view expanded

echo '== exact adapter and test diff =='
git diff --unified=100 "$base" "$head" -- src/sdp/disksage_catalog.py tests/test_disksage_catalog.py

echo '== exact API diff and DiskSage endpoint context =='
git diff --unified=70 "$base" "$head" -- src/sdp/api.py
git show "$head:src/sdp/api.py" | rg -n -A60 -B20 'disksage|DiskSageCatalogRequest|_authorize_graph_write\('

echo '== detector, validators, and ingestion at requested head =='
git show "$head:src/sdp/disksage_catalog.py" | nl -ba | sed -n '35,335p'

echo '== all privacy tests at requested head =='
git show "$head:tests/test_disksage_catalog.py" | nl -ba | sed -n '1,340p'

echo '== identity/upsert implementations at requested head =='
for f in src/sdp/disksage_catalog.py src/sdp/graph_store.py; do
  echo "----- $f -----"
  git show "$head:$f" | rg -n -A45 -B12 \
    'def (canonical|candidate|batch).*id|def upsert_node\(|def upsert_edge\(|cataloged_in|ON CONFLICT|PRIMARY KEY|UNIQUE' || true
done

echo '== exact dependency declaration and lock changes =='
git diff --unified=35 "$base" "$head" -- \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt
for f in pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt; do
  echo "----- $f at requested head -----"
  git show "$head:$f" 2>/dev/null | rg -n -A3 -B2 \
    '^(cryptography|PyJWT|fastapi|pydantic|psycopg|uvicorn)(\[.*\])?([=<>!~].*)?$|^cryptography==' || true
done

Length of output: 47590


🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='65e4fd770c69192daafe51854eb73eb2f06f0bf4'
base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'

show_range() {
  file="$1"
  start="$2"
  end="$3"
  echo "----- $file lines $start-$end at requested head -----"
  git show "$head:$file" | sed -n "${start},${end}p" | awk -v n="$start" '{printf "%d %s\n", n++, $0}'
}

show_range src/sdp/disksage_catalog.py 35 335
show_range tests/test_disksage_catalog.py 1 280

echo '== graph-store file candidates =='
git ls-tree -r --name-only "$head" src/sdp | rg '(^|/)(graph_store|authz|policy)\.py$'

echo '== graph identity, upsert, and constraints =='
for f in src/sdp/graph_store.py src/sdp/authz.py src/sdp/policy.py; do
  echo "----- $f -----"
  git show "$head:$f" | rg -n -A55 -B15 \
    'def upsert_node\(|def upsert_edge\(|def evaluate\(|def has_role\(|ON CONFLICT|PRIMARY KEY|UNIQUE|_SUBJECTS' || true
done

echo '== URL-pattern and path detector probes using static Python regex semantics =='
python3 - <<'PY'
import re
url = re.compile(r"[a-zA-Z][a-zA-Z0-9+.-]*://[^/\s]+(?:/[A-Za-z0-9._~%+-]*)*", re.I)
posix = re.compile(r"(?<![A-Za-z0-9])/(?:[^/\s]|\s|$)")
homewin = re.compile(r"(?:~/|[A-Za-z]:[\\/]|\\\\)")
cases = [
    "docs=https://example.com/disksage/catalog",
    "docs=https://example.com/a?next=/etc/sdp/secret.json",
    "docs=https://example.com/a#anchor",
    "docs=https://example.com/a%2Fb",
    "source=/",
    "source=/ ",
    "recording;/etc/sdp/secret.json",
    "recording|/tmp/disksage-preview.m4a",
]
for value in cases:
    stripped = url.sub(" ", value)
    print(repr(value), "=>", repr(stripped),
          "posix=", bool(posix.search(stripped)),
          "homewin=", bool(homewin.search(stripped)))
PY

echo '== exact documentation and dependency changes =='
git diff --unified=50 "$base" "$head" -- README.md docs/implementation-compliance.md \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt

echo '== dependency pins at requested head =='
for f in pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt; do
  echo "----- $f -----"
  git show "$head:$f" 2>/dev/null | rg -n -A4 -B3 \
    '^(cryptography|PyJWT|fastapi|pydantic|psycopg|uvicorn)(\[.*\])?([=<>!~].*)?$|^cryptography==' || true
done

Length of output: 114182


@seonghobae I reviewed exact head 65e4fd770c69192daafe51854eb73eb2f06f0bf4 against base e48aa13c4af7a4875d4b53e6a60b50405c265a2f.

Formal result: qualified.

I found no blocking PR-scoped issue by static inspection.

Verified items:

  • The checked-out HEAD equals the requested SHA.
  • The requested base is an ancestor of the requested head.
  • src/sdp/disksage_catalog.py rejects absolute POSIX path tokens after non-alphanumeric boundaries.
  • The detector rejects the prior /etc/..., /tmp/..., punctuation-delimited, root-only /, and source=/ cases.
  • The detector rejects file URIs, Windows paths, UNC paths, NUL bytes, and nested path-bearing metadata.
  • The HTTPS regression remains accepted.
  • Strict request models reject unknown fields.
  • The lineage validator requires selected production-time evidence.
  • The lineage validator rejects a lower-precedence selected source when recognized higher-precedence evidence exists.
  • src/sdp/api.py applies the existing admin graph-write policy before DiskSage ingestion.
  • Batch IDs use a canonical batch hash.
  • Candidate IDs use candidate fingerprints.
  • cataloged_in edges use deterministic source and target IDs.
  • The in-memory and Postgres graph stores implement keyed node and edge upserts.
  • cryptography==50.0.0 is consistent in pyproject.toml, requirements-test.in, requirements.txt, requirements-dev.txt, and requirements-test.txt.

I used the existing shared graph-write actor contract as PR scope context. I did not report it as a new DiskSage-specific finding.

I did not execute repository code or tests in this environment.


🧠 Learnings used
Learnt from: seonghobae
Repo: ContextualWisdomLab/semantic-data-portal PR: 0
File: :0-0
Timestamp: 2026-08-17T18:21:55.934Z
Learning: The DiskSage catalog ingestion endpoint at `src/sdp/api.py` uses the request-body `actor` field because this is the existing graph-write contract shared with `/graph/nodes` and `/graph/edges`. Changing that authorization contract is outside the scope of the DiskSage path-boundary PR.

You are interacting with an AI system.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please perform an independent formal review of exact current head 65e4fd770c69192daafe51854eb73eb2f06f0bf4 against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f.

The path-free detector now rejects any absolute POSIX token after a non-alphanumeric boundary, including /etc, /tmp, punctuation-delimited forms, ;/| separators, and a lone root /. HTTPS context remains accepted. Anchor every finding and any formal result only to this SHA.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Please perform an independent formal review of exact current head 65e4fd770c69192daafe51854eb73eb2f06f0bf4 against live base e48aa13c4af7a4875d4b53e6a60b50405c265a2f. Path-free DiskSage ingestion now rejects generic absolute POSIX tokens (/etc, /tmp), delimiter-independent leaks, and a lone root /. HTTPS context remains accepted. If the boundary is sound, submit a GitHub APPROVE on this exact SHA so last-push approval can proceed. Anchor any formal result only to this SHA.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='e48aa13c4af7a4875d4b53e6a60b50405c265a2f'
head='65e4fd770c69192daafe51854eb73eb2f06f0bf4'

echo '== Commit identity and ancestry =='
printf 'checked_out='; git rev-parse HEAD
printf 'base_type='; git cat-file -t "$base"
printf 'head_type='; git cat-file -t "$head"
printf 'merge_base='; git merge-base "$base" "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'

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

echo '== DiskSage adapter outline at requested head =='
git show "$head:src/sdp/disksage_catalog.py" > /tmp/disksage_catalog.py
ast-grep outline /tmp/disksage_catalog.py --items all --view expanded

echo '== Adapter, endpoint, and test diffs =='
git diff --unified=90 "$base" "$head" -- \
  src/sdp/disksage_catalog.py src/sdp/api.py tests/test_disksage_catalog.py

echo '== Exact path detector, schema, lineage, and ingestion =='
git show "$head:src/sdp/disksage_catalog.py" | nl -ba | sed -n '35,345p'

echo '== Exact DiskSage endpoint and graph-write authorization =='
git show "$head:src/sdp/api.py" | nl -ba | \
  rg -n -A70 -B25 'disksage|DiskSageCatalogRequest|_authorize_graph_write\('

echo '== Exact tests =='
git show "$head:tests/test_disksage_catalog.py" | nl -ba | sed -n '1,360p'

echo '== Graph identities, upserts, and policy definitions =='
for f in src/sdp/disksage_catalog.py src/sdp/graph_store.py src/sdp/authz.py src/sdp/policy.py; do
  echo "----- $f -----"
  git show "$head:$f" | rg -n -A55 -B15 \
    'def (canonical|candidate|batch).*id|def upsert_node\(|def upsert_edge\(|cataloged_in|def evaluate\(|def has_role\(|ON CONFLICT|PRIMARY KEY|UNIQUE' || true
done

echo '== Dependency changes and exact pins =='
git diff --unified=35 "$base" "$head" -- \
  pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt
for f in pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt; do
  echo "----- $f -----"
  git show "$head:$f" 2>/dev/null | rg -n -A3 -B2 \
    '^(cryptography|PyJWT|fastapi|pydantic|psycopg|uvicorn)(\[.*\])?([=<>!~].*)?$|^cryptography==' || true
done

Length of output: 40863


🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='65e4fd770c69192daafe51854eb73eb2f06f0bf4'

show_range() {
  file="$1"
  start="$2"
  end="$3"
  echo "----- $file:$start-$end at $head -----"
  git show "$head:$file" | sed -n "${start},${end}p" | awk -v line="$start" '{printf "%d: %s\n", line++, $0}'
}

show_range src/sdp/disksage_catalog.py 45 82
show_range src/sdp/disksage_catalog.py 145 218
show_range src/sdp/disksage_catalog.py 245 334
show_range src/sdp/api.py 690 780
show_range tests/test_disksage_catalog.py 70 227

echo '== Exact graph-store upsert methods and key constraints =='
git show "$head:src/sdp/graph_store.py" | \
  rg -n -A55 -B15 'def upsert_node\(|def upsert_edge\(|ON CONFLICT|PRIMARY KEY|UNIQUE|class (Memory|Postgres)'

echo '== Exact graph-write policy and role mapping =='
for f in src/sdp/authz.py src/sdp/policy.py; do
  echo "----- $f -----"
  git show "$head:$f" | rg -n -A55 -B15 'def evaluate\(|def has_role\(|_SUBJECTS|admin|action == "create"|action="create"'
done

echo '== Exact declared dependency pins =='
for f in pyproject.toml requirements.txt requirements-dev.txt requirements-test.in requirements-test.txt; do
  echo "----- $f -----"
  git show "$head:$f" | grep -nE '^(cryptography|PyJWT|fastapi|pydantic|psycopg|uvicorn)(\[.*\])?([=<>!~].*)?$|^cryptography==' || true
done

Length of output: 47810


@seonghobae I reviewed exact head 65e4fd770c69192daafe51854eb73eb2f06f0bf4 against base e48aa13c4af7a4875d4b53e6a60b50405c265a2f.

Formal result: qualified.

I found no blocking PR-scoped issue by static inspection.

Verified items:

  • The checked-out HEAD equals 65e4fd770c69192daafe51854eb73eb2f06f0bf4.
  • The requested base is an ancestor of this head.
  • src/sdp/disksage_catalog.py uses strict Pydantic models. Unknown request fields are rejected.
  • The adapter scans nested metadata values before persistence.
  • The adapter rejects NUL bytes, file: URIs, Windows paths, UNC paths, and absolute POSIX path tokens.
  • The POSIX detector rejects /etc/..., /tmp/..., punctuation-delimited paths, ; and | forms, /, and source=/ .
  • The HTTPS context regression remains accepted because URL stripping occurs before POSIX-path matching.
  • The lineage validator requires selected production-time evidence.
  • The lineage validator rejects a lower-precedence selected source when recognized higher-precedence evidence exists.
  • src/sdp/api.py Line 762 applies the existing admin graph-write policy before ingestion.
  • The adapter creates only catalog_batch and file_candidate nodes and cataloged_in edges.
  • Batch IDs use a canonical JSON hash. Candidate IDs use candidate fingerprints. Edge endpoints are deterministic.
  • The in-memory graph store updates nodes by node_id and edges by (edge_type, source_id, target_id).
  • The PostgreSQL graph store uses matching ON CONFLICT keys.
  • cryptography==50.0.0 is consistent in the inspected requirement input and lock files.

The request-body actor remains the existing shared graph-write contract. This PR does not introduce that behavior.

I did not execute repository code or tests in this environment.

You are interacting with an AI system.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

@opencode-agent opencode-agent Bot added priority: medium Normal-priority or P2 work status: needs-review Open pull request requiring current-head review or checks type: feature New or expanded product capability labels Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: medium Normal-priority or P2 work status: needs-review Open pull request requiring current-head review or checks type: feature New or expanded product capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants