Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
0f2db85
feat: extract shared Agent-construction wiring into noema-core
seonghobae Sep 2, 2026
2528854
test: expose noema-core packaging and CI gaps
seonghobae Sep 2, 2026
a8ea139
test: reproduce reviewer evidence import without noema-core path
seonghobae Sep 2, 2026
66e6a5d
fix: decouple evidence imports from noema-core runtime
seonghobae Sep 2, 2026
32b78b7
test: cover lazy reviewer runtime exports
seonghobae Sep 2, 2026
c9e22f5
fix(packaging): bundle shared core into reviewer wheel
seonghobae Sep 2, 2026
2d52b10
fix(core): require lock-validated PydanticAI API floor
seonghobae Sep 2, 2026
682f9f0
fix(ci): enforce shared-core gates and installed-wheel smoke
seonghobae Sep 2, 2026
37375a6
fix(deps): align reviewer input with validated PydanticAI floor
seonghobae Sep 2, 2026
e94ba8e
docs(adr): align shared-core rollout with installable packaging
seonghobae Sep 2, 2026
2d727ec
docs(reviewer): document installable shared-core packaging
seonghobae Sep 2, 2026
6bd8184
docs(core): align package status with wheel and CI contract
seonghobae Sep 2, 2026
656aeef
test(ci): reproduce invalid reviewer wheel smoke import
seonghobae Sep 2, 2026
49e8f8b
fix(ci): smoke the exported reviewer CLI parser
seonghobae Sep 2, 2026
e60f1dd
test(ddd): keep provider SDK wiring out of noema-core
seonghobae Sep 2, 2026
eed7cf1
fix(ddd): remove provider transport from noema-core
seonghobae Sep 2, 2026
07fb3dd
fix(ddd): narrow noema-core public surface
seonghobae Sep 2, 2026
708d55b
fix(ddd): keep orchestrator transport in reviewer adapter
seonghobae Sep 2, 2026
f66f9f3
test(ddd): verify injected-model agent construction
seonghobae Sep 2, 2026
f8ae2d9
fix(ddd): remove provider extra from noema-core
seonghobae Sep 2, 2026
0d9bd5f
test(ddd): keep provider extra at reviewer adapter
seonghobae Sep 2, 2026
aad5d74
docs(ddd): document provider-neutral core boundary
seonghobae Sep 2, 2026
6b730d4
test(package): expose reviewer sdist gap
seonghobae Sep 2, 2026
6c7c64f
fix(package): stage canonical core for reviewer builds
seonghobae Sep 2, 2026
6bf8313
fix(package): retain reviewer build backend in sdist
seonghobae Sep 2, 2026
aa12283
fix(package): make reviewer sdist self-contained
seonghobae Sep 2, 2026
f899483
fix(package): stage core for all PEP 517 hooks
seonghobae Sep 2, 2026
949da3c
chore(package): ignore reviewer build staging
seonghobae Sep 2, 2026
d4f3261
fix(package): exercise reviewer PEP 517 backend
seonghobae Sep 2, 2026
728ef67
test(package): lock self-contained reviewer sdist contract
seonghobae Sep 2, 2026
c3a1dd9
test(core): reject unresolved model routing strings
seonghobae Sep 2, 2026
5687bb0
fix(core): keep model routing outside shared kernel
seonghobae Sep 2, 2026
364e926
docs(core): require caller-resolved model adapters
seonghobae Sep 2, 2026
939cb8f
test(reviewer): block shared-core site-package leakage
seonghobae Sep 2, 2026
2b9fe6c
test(packaging): require PEP 660 editable hooks
seonghobae Sep 2, 2026
1826bb1
fix(packaging): preserve PEP 660 editable installs
seonghobae Sep 2, 2026
5da998d
test(reviewer): preserve independent-reviewer identity
seonghobae Sep 2, 2026
cb59e9a
fix(reviewer): preserve role identity and resolved-model boundary
seonghobae Sep 2, 2026
5b4201a
test(packaging): exercise clean editable reviewer install
seonghobae Sep 2, 2026
4f3dd33
fix(packaging): keep editable core linked to canonical source
seonghobae Sep 2, 2026
7c72bbe
fix(ci): use explicit empty PYTHONPATH assignment
seonghobae Sep 2, 2026
5363c6e
test(core): require composable role-neutral identity
seonghobae Sep 2, 2026
14891ae
fix(core): make shared Noema identity role-neutral
seonghobae Sep 2, 2026
485739e
fix(reviewer): compose bounded role from shared identity
seonghobae Sep 2, 2026
edd720c
docs(core): document role-neutral identity contract
seonghobae Sep 2, 2026
ab1ec25
test(packaging): reproduce staging races and editable clobbering
seonghobae Sep 2, 2026
a8a762f
test(packaging): require isolated editable installation contract
seonghobae Sep 2, 2026
7391746
fix(packaging): isolate reviewer build staging
seonghobae Sep 2, 2026
27e7ada
fix(packaging): reload staged setuptools context
seonghobae Sep 2, 2026
01f3264
test(packaging): expose isolated backend path loss
seonghobae Sep 2, 2026
1180465
test(packaging): parse editable smoke command tokens
seonghobae Sep 2, 2026
9fa70a3
fix(packaging): preserve isolated backend environment
seonghobae Sep 2, 2026
2dacd1a
Merge 9fa70a39f5a3de822df06afd14c5284ab1017e39 into 1a868c2dc64e7a949…
seonghobae Sep 2, 2026
7d0cc8d
Merge protected main into noema-core shared package
seonghobae Sep 3, 2026
a0c8744
docs(reviewer): align shared-core provider boundary
seonghobae Sep 3, 2026
6429c88
test(core): forbid shared-kernel retry authority
seonghobae Sep 3, 2026
482cb1a
fix(core): remove shared-kernel retry authority
seonghobae Sep 3, 2026
fe6e91f
fix(reviewer): keep retry authority outside noema-core
seonghobae Sep 3, 2026
7f92cee
docs(core): keep retry policy outside shared kernel
seonghobae Sep 3, 2026
d6c8c5e
fix(reviewer): explain intentional editable-link restaging
seonghobae Sep 3, 2026
02005d0
docs(changelog): record noema-core shared kernel
seonghobae Sep 3, 2026
2d2343b
fix(reviewer): remove empty exception handler
seonghobae Sep 3, 2026
ab74965
test(reviewer): isolate wheel install from source metadata
seonghobae Sep 3, 2026
cb49471
fix(reviewer): isolate wheel smoke installation
seonghobae Sep 3, 2026
a14cbe0
fix(ci): make wheel isolation contract indentation-agnostic
seonghobae Sep 4, 2026
5531a53
Merge protected main into noema-core package lane
seonghobae Sep 4, 2026
52b66ca
merge(reviewer): restack shared noema-core on protected reviewer foun…
seonghobae Sep 6, 2026
cf5dfa1
merge(context-fabric): restack shared noema-core on protected context…
seonghobae Sep 6, 2026
908d9cc
docs(release): restore noema-core Unreleased note
seonghobae Sep 6, 2026
6d6e0a4
merge: converge noema-core Shared Kernel onto protected #533 truth
seonghobae Sep 6, 2026
a1172fc
merge: converge noema-core Shared Kernel onto protected #552 truth
seonghobae Sep 6, 2026
8415e3c
merge: restack noema-core after #527 trust integration
seonghobae Sep 6, 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
2 changes: 1 addition & 1 deletion .github/workflows/central-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ jobs:
- name: Run independent PydanticAI review and publish current-head verdict
env:
GH_TOKEN: ${{ steps.noema_write_app.outputs.token }}
PYTHONPATH: ${{ github.workspace }}/reviewer
PYTHONPATH: ${{ github.workspace }}/reviewer:${{ github.workspace }}/packages/noema-core/src
Comment thread
seonghobae marked this conversation as resolved.
NOEMA_REVIEW_TOKEN_SOURCE: noema-github-app
NOEMA_LLM_API_URL: ${{ vars.NOEMA_LLM_API_URL }}
NOEMA_LLM_MODEL: ${{ vars.NOEMA_LLM_MODEL }}
Expand Down
89 changes: 88 additions & 1 deletion .github/workflows/reviewer-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
timeout-minutes: 30
env:
NOEMA_CODEGRAPH_SANDBOX_SOURCE_IMAGE: gcr.io/distroless/java-base-debian13:nonroot
PYTHONPATH: ${{ github.workspace }}/reviewer:${{ github.workspace }}/packages/noema-core/src
defaults:
run:
working-directory: reviewer
Expand Down Expand Up @@ -50,12 +51,98 @@ jobs:
- name: install (hash-pinned dependencies)
run: pip install --require-hashes --no-deps -r requirements-ci-hashes.txt

- name: test noema-core (100% line+branch coverage gate)
working-directory: packages/noema-core
run: python -m pytest

- name: docstring coverage noema-core (100% gate)
working-directory: packages/noema-core
run: python -m interrogate -c pyproject.toml src/noema_core

- name: test (100% line+branch coverage gate)
run: python -m pytest

- name: docstring coverage (100% gate)
run: python -m interrogate -c pyproject.toml noema_reviewer

- name: smoke-test installed reviewer wheel and sdist-to-wheel path
run: |
set -euo pipefail
wheel_dir="$RUNNER_TEMP/noema-reviewer-wheel"
sdist_dir="$RUNNER_TEMP/noema-reviewer-sdist"
sdist_wheel_dir="$RUNNER_TEMP/noema-reviewer-sdist-wheel"
direct_venv="$RUNNER_TEMP/noema-reviewer-install-smoke"
sdist_venv="$RUNNER_TEMP/noema-reviewer-sdist-install-smoke"
mkdir -p "$wheel_dir" "$sdist_dir" "$sdist_wheel_dir"

python -m pip wheel . --no-deps --no-build-isolation --wheel-dir "$wheel_dir"
direct_wheel="$(find "$wheel_dir" -maxdepth 1 -type f -name 'noema_reviewer-*.whl' -print -quit)"
test -n "$direct_wheel"

SDIST_DIR="$sdist_dir" SDIST_NAME_FILE="$RUNNER_TEMP/noema-reviewer-sdist-name" python - <<'PY'
import os
from pathlib import Path
from build_backend import build_sdist

sdist_name = build_sdist(os.environ["SDIST_DIR"])
Path(os.environ["SDIST_NAME_FILE"]).write_text(sdist_name, encoding="utf-8")
PY
sdist="$sdist_dir/$(cat "$RUNNER_TEMP/noema-reviewer-sdist-name")"
test -f "$sdist"
python -m pip wheel "$sdist" --no-deps --no-build-isolation --wheel-dir "$sdist_wheel_dir"
sdist_wheel="$(find "$sdist_wheel_dir" -maxdepth 1 -type f -name 'noema_reviewer-*.whl' -print -quit)"
test -n "$sdist_wheel"

for contract in direct sdist; do
if [ "$contract" = direct ]; then
wheel="$direct_wheel"
venv_dir="$direct_venv"
else
wheel="$sdist_wheel"
venv_dir="$sdist_venv"
fi
python -m venv --system-site-packages "$venv_dir"
(
cd "$RUNNER_TEMP"
PYTHONPATH='' "$venv_dir/bin/python" -m pip install --no-deps "$wheel"
PYTHONPATH='' "$venv_dir/bin/python" - <<'PY'
import hashlib
import os
from pathlib import Path

import noema_core
import noema_core.agent
import noema_reviewer
from noema_reviewer.cli import parse_args

canonical_agent = Path(os.environ["GITHUB_WORKSPACE"]) / "packages" / "noema-core" / "src" / "noema_core" / "agent.py"
installed_agent = Path(noema_core.agent.__file__)
assert hashlib.sha256(installed_agent.read_bytes()).digest() == hashlib.sha256(canonical_agent.read_bytes()).digest()
assert noema_core.NOEMA_PERSONA
assert noema_reviewer.build_agent is not None
assert parse_args([]).repo == ""
Comment thread
seonghobae marked this conversation as resolved.
PY
)
done

- name: smoke-test isolated editable reviewer with locked runtime dependencies
run: |
set -euo pipefail
editable_venv="$RUNNER_TEMP/noema-reviewer-editable-smoke"
python -m venv "$editable_venv"
"$editable_venv/bin/python" -m pip install --require-hashes --no-deps -r requirements-ci-hashes.txt
"$editable_venv/bin/python" -m pip install --no-deps -e .
(
cd "$RUNNER_TEMP"
PYTHONPATH='' "$editable_venv/bin/python" - <<'PY'
import noema_core
import noema_reviewer

assert noema_core.build_agent is not None
assert noema_reviewer.build_agent is not None
PY
)

- name: install lock-pinned CodeGraph tooling for sandbox smoke test
env:
NPM_CONFIG_IGNORE_SCRIPTS: "true"
Expand Down Expand Up @@ -98,7 +185,7 @@ jobs:
source_root="$RUNNER_TEMP/noema-codegraph-smoke"
mkdir -p "$source_root"
printf 'export const commercialReadiness = true;\n' >"$source_root/example.ts"
PYTHONPATH=. python - <<'PY'
python - <<'PY'
import os
from noema_reviewer.sandbox import DockerCodeGraphRunner

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ exchange-30d.ndjson
exchange-30d.ndjson.provenance.json
noema-kpi-evidence.json
noema-smoke-evidence.json
reviewer/_build_include/
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## Unreleased
- `noema-core` provider-neutral Shared Kernel을 추가하여 이미 해석된 PydanticAI `Model`과 역할별 prompt/schema만 받아 Agent를 구성한다. 문자열 model identifier와 provider discovery·credential·routing·retry·failover는 Shared Kernel 밖에 두고 `Agent(..., retries=0)`으로 repository-local model-attempt authority를 만들지 않는다. Reviewer wheel·sdist·editable 설치는 canonical `packages/noema-core` source를 포함하거나 참조하며 별도 100% coverage·docstring과 clean install smoke로 검증한다. 외부 소비는 immutable versioned publication·exact source identity·SBOM/provenance·licensing/NOTICE·compatibility/rollback evidence 전에는 허용하지 않는다.
- Noema reviewer의 strict changed-file evidence를 historical 12-file prefix에서 canonical 80-file CodeGraph scope와 일치시켰다. 13–80 file PR은 선택된 모든 current-head file context를 유지하고 81개 이상은 기존처럼 실패-폐쇄하며, local CodeGraph fallback의 `HOME`·`TEMP`·`TMP`·`TMPDIR`은 ambient host path를 상속하지 않고 실행마다 새 private temporary directory로 격리한다.
- Workflow / Task Execution은 untrusted DAG를 execution/plan identity에 결합한 detached immutable snapshot으로 승인하고, validated array bounds 안에서만 task/dependency/state evidence를 읽는다. runnable 선택은 cross-execution·foreign·duplicate·non-canonical evidence, admitted concurrency를 초과한 running state, 성공하지 않은 prerequisite 뒤에 존재하는 causally impossible executed state를 실패-폐쇄하며, 선택 결과는 reservation이나 side-effect authority가 아닌 후보임을 명시한다. Agent Runtime lifecycle·State & Checkpoint·Workflow admission은 null·throwing accessor·revoked proxy 같은 malformed runtime input의 임의 JavaScript 예외를 각 bounded-context domain error로 정규화한다.
- State & Checkpoint admission은 accepted/replay 결과와 내부 checkpoint를 모두 caller-owned alias에서 분리한 frozen snapshot으로 반환한다. TypeScript `readonly`만으로는 막을 수 없는 JavaScript 런타임 alias mutation이 승인된 checkpoint authority나 `accepted`/`replay` 분류를 사후 변경하지 못하도록 실패-폐쇄한다.
Expand Down
100 changes: 100 additions & 0 deletions docs/adr/0014-shared-noema-core-package.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# ADR-0014: Minimal `noema-core` Shared Kernel for Agent construction

- **Status:** Proposed
- **Decision owner:** Noema repository governance
- **Scope:** `ContextualWisdomLab/noema` reviewer self-consumption and future versioned consumers

## Problem

Noema has multiple bounded-context consumers that need the same PydanticAI `Agent(...)` construction semantics, but those consumers do not share domain authority. Repeating the framework construction call in each consumer creates drift; centralizing model discovery, provider SDKs, credentials, fallback, retry policy, verdict schemas, tools, tenant state, or security policy would instead violate the repository's DDD boundary and duplicate canonical owners.

The previous branch-local ADR used number `0012`, which now belongs on protected `main` to the runtime bounded-context decision. ADR identity is immutable repository architecture authority, so this decision is renumbered to `0014` rather than retaining two different ADR-0012 documents.

## Constraints

- `contextual-orchestrator` owns provider/model discovery, routing, test-time compute, provider/model retry and failover, provider credentials and provider-specific transport policy.
- Noema owns Agent Runtime and its bounded contexts, not foreign product truth.
- Reviewer verdict schema, deterministic gates, GitHub evidence policy and reviewer publication remain reviewer-owned.
- Tenant/application tool authority and domain state stay in their owning product.
- Security isolation, quarantine and outbound-policy authority stay with their canonical owners.
- Mutable branch refs and copied source are not acceptable cross-repository dependencies.
- External adoption requires an immutable versioned publication with exact source identity and compatibility evidence.

## Alternatives

### A. Duplicate the construction in every consumer

Rejected. It preserves local autonomy but guarantees repeated framework wiring and version drift without adding a useful bounded-context distinction.

### B. Put provider discovery, retry or transport in `noema-core`

Rejected. That would recreate `contextual-orchestrator` policy inside Noema and would let a Shared Kernel become an ambient provider/model-attempt authority boundary.

### C. Build an always-on Noema service for every consumer

Rejected for this phase. A service would add deployment, network, authorization and recovery semantics that are not required to remove the verified same-language construction duplication. Cross-language consumers can be handled through released service/API contracts when a real caller requires them.

### D. Minimal package with caller-supplied model

Chosen. `packages/noema-core` owns only a role-neutral Noema persona fragment and a factory that accepts an already-constructed PydanticAI `Model` and calls `Agent(...)` with caller-owned prompt, output and deps types. The factory fixes PydanticAI model-attempt retries to zero instead of exposing a reusable retry knob; orchestration-level retry/failover remains with `contextual-orchestrator`.

## Decision

Create `packages/noema-core` as a minimal Shared Kernel with:

- `NOEMA_PERSONA = "You are Noema"` as a role-neutral identity prefix;
- `build_agent(model, *, system_prompt, output_type=str, deps_type=None)`;
- rejection of string model identifiers so PydanticAI's implicit provider/model inference cannot move discovery into the Shared Kernel;
- no caller-visible `retries` parameter and `Agent(..., retries=0)` at this boundary so the Shared Kernel cannot silently create additional model attempts outside the orchestrator contract.

`noema-core` deliberately does **not** own:

- provider SDK construction or endpoint selection;
- credentials, key discovery, model groups, retries or fallback;
- reviewer verdicts, gates or merge authority;
- tool/dependency authorization;
- tenant isolation, domain persistence or foreign truth;
- quarantine, egress or malware/security verdict authority.

The current PR's only production consumer is `reviewer/noema_reviewer`. Reviewer packaging stages the canonical `packages/noema-core/src/noema_core` source into wheel/sdist builds so the installed reviewer contains the exact shared module without copying a second source tree. Editable installs and CI use the same canonical path. This is a transitional monorepo packaging arrangement, not permission for external repositories to consume the mutable branch.

## Verification contract

Before this decision can become `Accepted`, the exact candidate head must prove:

1. `packages/noema-core` line and branch coverage are 100% and public docstring coverage is 100%.
2. The reviewer retains its existing coverage/docstring gates and behavior.
3. Installed reviewer wheel and sdist-to-wheel smoke tests import both `noema_reviewer` and `noema_core` outside the checkout and prove the installed shared `agent.py` bytes match the canonical source.
4. Evidence-only reviewer imports remain lazy and do not require model construction.
5. String model identifiers fail closed at the Shared Kernel boundary.
6. `build_agent` exposes no retry-policy argument and constructs the PydanticAI agent with model-attempt retries disabled; provider/model retry and failover remain contextual-orchestrator authority.
7. Central review execution receives the canonical package path without moving provider routing authority into Noema.
8. No cross-repository consumer adopts `noema-core` until immutable publication exists.

## Publication boundary

A merge of this PR establishes protected source, not an external dependency. External consumption requires the repository's selected immutable publication mechanism to provide all applicable evidence together:

- semantic version and immutable source commit;
- artifact digest/integrity;
- package/install smoke tests;
- SBOM and provenance;
- licensing/NOTICE compatibility;
- compatibility/migration and rollback guidance.

After such a release exists, consumers must pin the released version through their own ACL/adapter and regenerate their exact-head acceptance evidence. A mutable Git branch, local path, copied module, or open PR head is never the production dependency.

## Consequences

The shared surface stays intentionally small, so framework construction drift is removed without turning Noema into an LLM gateway or a domain super-service. The cost is a transitional reviewer build backend until `noema-core` has its own immutable package publication. That transitional backend must remain bounded, deterministic and covered by installed-artifact tests.

Removing the retry argument is intentionally restrictive. A consumer that needs a different attempt policy must not add a local convenience knob to the Shared Kernel; it must use the released contextual-orchestrator contract or make a separately reviewed bounded-context decision that does not duplicate provider/model retry authority.

A future need for cross-language access is a separate architecture decision. It should begin from a real consumer and released contract rather than expanding this package pre-emptively.

## Follow-up

- Merge the reviewer self-consumption only after current-head CI, security, reviewer, package and provenance gates pass.
- Publish `noema-core` through the repository-approved immutable mechanism when release evidence is ready.
- Replace transitional monorepo bundling with a normal released dependency after publication.
- Update any future consumer only after verifying its canonical owner boundary and exact released artifact identity.
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ ADR은 **왜 이 구조를 선택했는지**를 기록합니다. 구현 상태
| [0010](./0010-private-target-review-auth.md) | Proposed | private review target의 첫 live PR lookup부터 single-repository Noema App token을 사용하고 workflow `GITHUB_TOKEN` cross-repository fallback을 금지한다. |
| [0011](./0011-independent-reviewer-governance.md) | Proposed | qualifying formal approval의 eligibility·exact-head·staleness를 검증하고 check/status/scanner/model evidence가 approval을 대체하지 못하게 한다. |
| [0012](./0012-runtime-orchestration-bounded-contexts.md) | Proposed | Agent Runtime, Workflow / Task Execution, Tool / Capability, State / Checkpoint, isolation, policy, observability, recovery의 소유권을 분리하고 provider routing·foreign truth·cross-service SQL을 Noema 경계 밖에 둔다. |
| [0014](./0014-shared-noema-core-package.md) | Proposed | role-neutral PydanticAI `Agent(...)` construction만 `packages/noema-core` Shared Kernel로 추출하고 provider routing·credential policy·verdict·tool/deps·tenant truth는 canonical owner에 남긴다. |

## ADR lifecycle

Expand Down
5 changes: 5 additions & 0 deletions packages/noema-core/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
__pycache__/
*.pyc
.coverage
.pytest_cache/
*.egg-info/
55 changes: 55 additions & 0 deletions packages/noema-core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# noema-core

Provider-neutral PydanticAI `Agent` construction shared by Noema's per-context
consumers. See [`docs/adr/0014-shared-noema-core-package.md`](../../docs/adr/0014-shared-noema-core-package.md)
for the decision and its scope boundary.

## What this package is

One function and one role-neutral identity fragment shared without moving
provider or bounded-context authority into Noema:

- `build_agent(model, *, system_prompt, output_type=str, deps_type=None, retries=3) -> Agent`
Comment thread
coderabbitai[bot] marked this conversation as resolved.
constructs an agent around a caller-supplied, already constructed PydanticAI
`Model`. String model names are rejected so provider/model discovery cannot
occur inside the Shared Kernel.
- `NOEMA_PERSONA` is exactly `"You are Noema"`. Consumers compose that stable
identity with their own precise role, organization context, evidence rules,
tool authority and output contract; the Shared Kernel does not assign a
generic role that could weaken a specialized reviewer or runtime agent.

The injected model is deliberate. `noema-core` does not construct `AsyncOpenAI`,
`OpenAIChatModel`, `OpenAIProvider`, provider credentials, model discovery,
routing or failover. A consuming bounded context may own a transport adapter to
the published `contextual-orchestrator` interface, but that adapter does not
become Shared Kernel authority.

## What this package explicitly is not

It does not own a verdict/output schema, tool/deps machinery, credential
resolution or validation policy, provider SDK, routing policy, provider
fallback, or tenant isolation. Those stay with their canonical owners.

## Status

Self-consumption only: `reviewer/noema_reviewer` is the sole consumer today.
`noema-core` is not yet published to an immutable package index, so external
consumers must not pin a mutable branch or copy this source. During this
transition the `noema-reviewer` distribution includes `noema_core` from this
single canonical source path through the custom packaging backend. Wheel and
sdist builds stage a bounded snapshot; editable installs keep an ignored
canonical-source view so their package mapping remains valid after the PEP 660
hook completes. Required `reviewer-ci` runs this package's 100% line/branch and
docstring gates and validates installed distributions outside the checkout.

Publishing `noema-core` through the repository's selected immutable package
mechanism and moving consumers to a normal versioned dependency are tracked as
follow-ups in the ADR.

## Develop

```bash
pip install -e .
python -m pytest # 100% line+branch coverage gate
python -m interrogate -c pyproject.toml src/noema_core # 100% docstring gate
```
Loading
Loading