Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
4f001ae
feat(llm): route remaining jobs through contextual-orchestrator
cursoragent Aug 16, 2026
4aa81e0
fix(llm): remove sequential fallback from reviewer and gateway
cursoragent Aug 16, 2026
3661db8
test(llm): cover non-Error CLI failures and empty-host URL parsing
cursoragent Aug 16, 2026
67196e7
test(reviewer): attach leftover-fallback parametrize to the right case
cursoragent Aug 16, 2026
1705102
feat(llm): publish reusable orchestrator contract for naruon
cursoragent Aug 16, 2026
90ae7a6
merge main into contextual-orchestrator gateway
seonghobae Aug 16, 2026
325783e
docs: preserve orchestrator cutover changelog
seonghobae Aug 16, 2026
a169b1d
test(security): refuse oversized orchestrator health body before read
seonghobae Aug 16, 2026
c0536fb
fix(security): reject oversized orchestrator health body before read
seonghobae Aug 16, 2026
b0c1ae6
test(security): bound chunked orchestrator health response
seonghobae Aug 16, 2026
6d8d036
fix(security): stream-bound orchestrator health response
seonghobae Aug 16, 2026
87b7114
test(reliability): keep orchestrator timeout across body read
seonghobae Aug 16, 2026
bc8f4cc
test(security): reject ambiguous orchestrator health JSON
seonghobae Aug 16, 2026
0b6b317
fix(security): reject ambiguous orchestrator health JSON
seonghobae Aug 16, 2026
8c380a7
test(security): exercise decoded duplicate health identity key
seonghobae Aug 16, 2026
3a32396
test(orchestrator): reject routing alias override
seonghobae Aug 16, 2026
547e099
fix(orchestrator): pin production routing alias
seonghobae Aug 16, 2026
1532c22
test(orchestrator): pin shared routing alias
seonghobae Aug 16, 2026
77efdb6
fix(orchestrator): enforce canonical routing alias
seonghobae Aug 16, 2026
87f7002
test(security): forbid raw orchestrator secret env reads
seonghobae Aug 16, 2026
5e72414
test(security): scope orchestrator secret-source regression
seonghobae Aug 16, 2026
f82d68e
fix(security): keep orchestrator preflight secret-free
seonghobae Aug 16, 2026
207bb65
test(security): align gateway preflight with secret-free contract
seonghobae Aug 16, 2026
64f62f6
fix(security): filter gateway preflight process environment
seonghobae Aug 16, 2026
2abe7bd
test(security): cover secret-free preflight process adapter
seonghobae Aug 16, 2026
6271f49
fix(security): keep gateway preflight uncredentialed
seonghobae Aug 16, 2026
da803c1
test(security): pin uncredentialed gateway preflight workflow
seonghobae Aug 16, 2026
8a91762
test(security): keep reusable gateway verifier secret-free
seonghobae Aug 16, 2026
6559882
fix(security): remove secret read from reusable gateway verifier
seonghobae Aug 16, 2026
83931ae
test(security): make gateway contract secret-free
seonghobae Aug 16, 2026
35dae9c
test(security): reject secret gateway transport reads
seonghobae Aug 16, 2026
e71f6b6
fix(security): allowlist non-secret gateway transport names
seonghobae Aug 16, 2026
4d10f48
test(security): cover non-secret gateway transport allowlist
seonghobae Aug 16, 2026
171a542
test(security): reject direct-provider root-dot aliases
seonghobae Aug 16, 2026
b755c07
fix(security): canonicalize direct-provider DNS root dots
seonghobae Aug 16, 2026
577b3df
test(security): reject empty canonical gateway hosts
seonghobae Aug 16, 2026
5e6ecaa
fix(security): reject empty canonical gateway hosts
seonghobae Aug 16, 2026
1b094b7
test: isolate expected gateway CLI diagnostics
seonghobae Aug 16, 2026
cdaed6c
fix(ci): isolate expected gateway preflight diagnostics
seonghobae Aug 16, 2026
cee047e
Merge cdaed6ca84b992abe5541b0ee6ac07cd695bfe9a into db21df28691fbea63…
seonghobae Aug 16, 2026
10577e5
Merge cee047e56caa03f004f0132153695b94dd226cbb into f5c41fcbb55200e43…
seonghobae Aug 16, 2026
c5171e6
test(ci): require live-base identity binding
seonghobae Aug 17, 2026
c4ebbcc
fix(ci): bind verification to fresh live base
seonghobae Aug 17, 2026
c87c7a6
test(ci): align lockfile guard with live base
seonghobae Aug 17, 2026
1563315
test(ci): assert fresh live-base contract
seonghobae Aug 17, 2026
a77111a
merge(main): integrate acquisition data-room hardening
seonghobae Aug 17, 2026
9743cb3
test(acquisition): preserve orchestrator gateway evidence entries
seonghobae Aug 17, 2026
7ee2f2a
test(acquisition): target composed gateway catalog
seonghobae Aug 17, 2026
73a1789
fix(acquisition): compose gateway evidence catalog
seonghobae Aug 17, 2026
1ef9d87
fix(acquisition): use composed gateway catalog
seonghobae Aug 17, 2026
24975a4
fix(acquisition): verify composed gateway catalog
seonghobae Aug 17, 2026
496d3f2
test(coverage): include composed acquisition catalog
seonghobae Aug 17, 2026
4185c14
test(acquisition): execute composed data-room catalog
seonghobae Aug 17, 2026
948e73c
test(ci): capture expected gateway preflight failure
seonghobae Aug 17, 2026
2149cd7
test(orchestrator): cover non-Error health rejection
seonghobae Aug 17, 2026
83ec02d
chore(stack): merge protected OIDC coverage slice
seonghobae Aug 17, 2026
d1f9993
chore(stack): merge current protected coverage slices
seonghobae Aug 17, 2026
fd20048
test(orchestrator): cover residual health boundaries
seonghobae Aug 17, 2026
05be467
refactor(orchestrator): remove unreachable empty-host guard
seonghobae Aug 17, 2026
c8b18ff
refactor(orchestrator): rely on URL host validation
seonghobae Aug 17, 2026
c419f18
fix(gateway): reject empty canonical hostnames
seonghobae Aug 17, 2026
85626a7
test(gateway): cover oversized array-buffer fallback
seonghobae Aug 17, 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
54 changes: 1 addition & 53 deletions .github/workflows/central-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -442,59 +442,7 @@ jobs:
NOEMA_LLM_MAX_RETRIES: ${{ vars.NOEMA_LLM_MAX_RETRIES || '1' }}
run: |
set -euo pipefail
python - <<'PY'
import json
import os
from urllib.parse import urlsplit, urlunsplit
from urllib.request import Request, urlopen

api_url = os.environ.get("NOEMA_LLM_API_URL", "").strip()
api_key = os.environ.get("NOEMA_LLM_API_KEY", "").strip()
try:
parsed = urlsplit(api_url)
if parsed.scheme != "https" or not parsed.hostname:
raise ValueError("NOEMA_LLM_API_URL must be an absolute HTTPS URL")
if parsed.username or parsed.password or parsed.query or parsed.fragment:
raise ValueError(
"NOEMA_LLM_API_URL must not contain credentials, query, or fragment"
)
if parsed.hostname.lower() in {
"api.openai.com",
"models.github.ai",
"openrouter.ai",
}:
raise ValueError(
"Noema production review must use contextual-orchestrator, "
"not a direct model provider"
)
path = parsed.path.rstrip("/")
if not path.endswith("/v1"):
raise ValueError("NOEMA_LLM_API_URL must end in /v1")
if not api_key:
raise ValueError("NOEMA_LLM_API_KEY is not configured")
health_path = f"{path[:-3]}/healthz" or "/healthz"
health_url = urlunsplit(
(parsed.scheme, parsed.netloc, health_path, "", "")
)
request = Request(
health_url,
headers={"Accept": "application/json", "User-Agent": "noema-reviewer"},
)
with urlopen(request, timeout=15) as response: # noqa: S310 - trusted org variable
raw = response.read(65_537)
if len(raw) > 65_536:
raise ValueError("contextual-orchestrator health response is too large")
health = json.loads(raw)
if health.get("status") != "ok" or health.get("service") != "contextual-orchestrator":
raise ValueError(
"NOEMA_LLM_API_URL did not identify contextual-orchestrator"
)
except Exception as exc:
print(f"::error::Noema contextual-orchestrator preflight failed: {exc}")
raise SystemExit(1) from exc

print("Verified contextual-orchestrator gateway identity.")
PY
node scripts/verify-orchestrator-gateway.mjs
printf 'Noema provider contract: gateway=contextual-orchestrator primary=%s timeout=%ss retries=%s.\n' \
"${NOEMA_LLM_MODEL:-missing}" "${NOEMA_LLM_REQUEST_TIMEOUT_SECONDS:-missing}" \
"${NOEMA_LLM_MAX_RETRIES:-missing}"
Expand Down
34 changes: 15 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
NOEMA_PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
NOEMA_PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
NOEMA_EXPECTED_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
if [[ ! "$NOEMA_PR_BASE_SHA" =~ ^[0-9a-f]{40}$ ]]; then
printf '::error::Invalid pull-request base SHA.\n'
if [[ ! "$NOEMA_EXPECTED_HEAD_SHA" =~ ^[0-9a-f]{40}$ ]]; then
printf '::error::Invalid expected head SHA.\n'
exit 1
fi
if [ -z "$NOEMA_PR_BASE_REF" ]; then
Expand All @@ -80,28 +80,25 @@ jobs:
printf '::error::Live pull-request base ref did not resolve to a full commit SHA.\n'
exit 1
fi
if [ "$live_base_sha" != "$NOEMA_PR_BASE_SHA" ]; then
printf '::error::Pull-request base branch advanced from %s to %s.\n' \
"$NOEMA_PR_BASE_SHA" "$live_base_sha"
if ! git merge-base --is-ancestor "$live_base_sha" "$NOEMA_EXPECTED_HEAD_SHA"; then
printf '::error::Pull-request head does not contain the current live base %s.\n' "$live_base_sha"
exit 1
fi
test "$live_base_sha" = "$NOEMA_PR_BASE_SHA"
printf 'NOEMA_LIVE_BASE_SHA=%s\n' "$live_base_sha" >> "$GITHUB_ENV"

- name: verify lockfile change control
if: github.event_name == 'pull_request'
shell: bash
env:
NOEMA_PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: |
set -euo pipefail
if [[ ! "$NOEMA_PR_BASE_SHA" =~ ^[0-9a-f]{40}$ ]]; then
printf '::error::Invalid pull-request base SHA.\n'
if [[ ! "$NOEMA_LIVE_BASE_SHA" =~ ^[0-9a-f]{40}$ ]]; then
printf '::error::Invalid live pull-request base SHA.\n'
exit 1
fi
base_lock="$RUNNER_TEMP/noema-package-lock-base.json"
git show "${NOEMA_PR_BASE_SHA}:package-lock.json" >"$base_lock"
git show "${NOEMA_LIVE_BASE_SHA}:package-lock.json" >"$base_lock"
NOEMA_LOCKFILE_BASE_PATH="$base_lock" \
NOEMA_LOCKFILE_BASE_SHA="$NOEMA_PR_BASE_SHA" \
NOEMA_LOCKFILE_BASE_SHA="$NOEMA_LIVE_BASE_SHA" \
node --input-type=module <<'NODE'
import { runLockfileChangeControl } from "./scripts/lockfile-change-control.mjs";

Expand All @@ -127,11 +124,10 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
NOEMA_PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
NOEMA_PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: |
set -euo pipefail
if [[ ! "$NOEMA_PR_BASE_SHA" =~ ^[0-9a-f]{40}$ ]]; then
printf '::error::Invalid pull-request base SHA.\n'
if [[ ! "$NOEMA_LIVE_BASE_SHA" =~ ^[0-9a-f]{40}$ ]]; then
printf '::error::Initial live pull-request base SHA is unavailable.\n'
exit 1
fi
if [ -z "$NOEMA_PR_BASE_REF" ]; then
Expand All @@ -151,9 +147,9 @@ jobs:
printf '::error::Live pull-request base ref did not resolve to a full commit SHA.\n'
exit 1
fi
if [ "$live_base_sha" != "$NOEMA_PR_BASE_SHA" ]; then
if [ "$live_base_sha" != "$NOEMA_LIVE_BASE_SHA" ]; then
printf '::error::Pull-request base branch advanced during verification from %s to %s.\n' \
"$NOEMA_PR_BASE_SHA" "$live_base_sha"
"$NOEMA_LIVE_BASE_SHA" "$live_base_sha"
exit 1
fi
test "$live_base_sha" = "$NOEMA_PR_BASE_SHA"
test "$live_base_sha" = "$NOEMA_LIVE_BASE_SHA"
Loading
Loading