-
Notifications
You must be signed in to change notification settings - Fork 0
feat(reviewer): extract shared noema-core package (ADR-0014) #536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
seonghobae
wants to merge
72
commits into
main
Choose a base branch
from
feat/noema-core-shared-agent-wiring
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
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 2528854
test: expose noema-core packaging and CI gaps
seonghobae a8ea139
test: reproduce reviewer evidence import without noema-core path
seonghobae 66e6a5d
fix: decouple evidence imports from noema-core runtime
seonghobae 32b78b7
test: cover lazy reviewer runtime exports
seonghobae c9e22f5
fix(packaging): bundle shared core into reviewer wheel
seonghobae 2d52b10
fix(core): require lock-validated PydanticAI API floor
seonghobae 682f9f0
fix(ci): enforce shared-core gates and installed-wheel smoke
seonghobae 37375a6
fix(deps): align reviewer input with validated PydanticAI floor
seonghobae e94ba8e
docs(adr): align shared-core rollout with installable packaging
seonghobae 2d727ec
docs(reviewer): document installable shared-core packaging
seonghobae 6bd8184
docs(core): align package status with wheel and CI contract
seonghobae 656aeef
test(ci): reproduce invalid reviewer wheel smoke import
seonghobae 49e8f8b
fix(ci): smoke the exported reviewer CLI parser
seonghobae e60f1dd
test(ddd): keep provider SDK wiring out of noema-core
seonghobae eed7cf1
fix(ddd): remove provider transport from noema-core
seonghobae 07fb3dd
fix(ddd): narrow noema-core public surface
seonghobae 708d55b
fix(ddd): keep orchestrator transport in reviewer adapter
seonghobae f66f9f3
test(ddd): verify injected-model agent construction
seonghobae f8ae2d9
fix(ddd): remove provider extra from noema-core
seonghobae 0d9bd5f
test(ddd): keep provider extra at reviewer adapter
seonghobae aad5d74
docs(ddd): document provider-neutral core boundary
seonghobae 6b730d4
test(package): expose reviewer sdist gap
seonghobae 6c7c64f
fix(package): stage canonical core for reviewer builds
seonghobae 6bf8313
fix(package): retain reviewer build backend in sdist
seonghobae aa12283
fix(package): make reviewer sdist self-contained
seonghobae f899483
fix(package): stage core for all PEP 517 hooks
seonghobae 949da3c
chore(package): ignore reviewer build staging
seonghobae d4f3261
fix(package): exercise reviewer PEP 517 backend
seonghobae 728ef67
test(package): lock self-contained reviewer sdist contract
seonghobae c3a1dd9
test(core): reject unresolved model routing strings
seonghobae 5687bb0
fix(core): keep model routing outside shared kernel
seonghobae 364e926
docs(core): require caller-resolved model adapters
seonghobae 939cb8f
test(reviewer): block shared-core site-package leakage
seonghobae 2b9fe6c
test(packaging): require PEP 660 editable hooks
seonghobae 1826bb1
fix(packaging): preserve PEP 660 editable installs
seonghobae 5da998d
test(reviewer): preserve independent-reviewer identity
seonghobae cb59e9a
fix(reviewer): preserve role identity and resolved-model boundary
seonghobae 5b4201a
test(packaging): exercise clean editable reviewer install
seonghobae 4f3dd33
fix(packaging): keep editable core linked to canonical source
seonghobae 7c72bbe
fix(ci): use explicit empty PYTHONPATH assignment
seonghobae 5363c6e
test(core): require composable role-neutral identity
seonghobae 14891ae
fix(core): make shared Noema identity role-neutral
seonghobae 485739e
fix(reviewer): compose bounded role from shared identity
seonghobae edd720c
docs(core): document role-neutral identity contract
seonghobae ab1ec25
test(packaging): reproduce staging races and editable clobbering
seonghobae a8a762f
test(packaging): require isolated editable installation contract
seonghobae 7391746
fix(packaging): isolate reviewer build staging
seonghobae 27e7ada
fix(packaging): reload staged setuptools context
seonghobae 01f3264
test(packaging): expose isolated backend path loss
seonghobae 1180465
test(packaging): parse editable smoke command tokens
seonghobae 9fa70a3
fix(packaging): preserve isolated backend environment
seonghobae 2dacd1a
Merge 9fa70a39f5a3de822df06afd14c5284ab1017e39 into 1a868c2dc64e7a949…
seonghobae 7d0cc8d
Merge protected main into noema-core shared package
seonghobae a0c8744
docs(reviewer): align shared-core provider boundary
seonghobae 6429c88
test(core): forbid shared-kernel retry authority
seonghobae 482cb1a
fix(core): remove shared-kernel retry authority
seonghobae fe6e91f
fix(reviewer): keep retry authority outside noema-core
seonghobae 7f92cee
docs(core): keep retry policy outside shared kernel
seonghobae d6c8c5e
fix(reviewer): explain intentional editable-link restaging
seonghobae 02005d0
docs(changelog): record noema-core shared kernel
seonghobae 2d2343b
fix(reviewer): remove empty exception handler
seonghobae ab74965
test(reviewer): isolate wheel install from source metadata
seonghobae cb49471
fix(reviewer): isolate wheel smoke installation
seonghobae a14cbe0
fix(ci): make wheel isolation contract indentation-agnostic
seonghobae 5531a53
Merge protected main into noema-core package lane
seonghobae 52b66ca
merge(reviewer): restack shared noema-core on protected reviewer foun…
seonghobae cf5dfa1
merge(context-fabric): restack shared noema-core on protected context…
seonghobae 908d9cc
docs(release): restore noema-core Unreleased note
seonghobae 6d6e0a4
merge: converge noema-core Shared Kernel onto protected #533 truth
seonghobae a1172fc
merge: converge noema-core Shared Kernel onto protected #552 truth
seonghobae 8415e3c
merge: restack noema-core after #527 trust integration
seonghobae File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| __pycache__/ | ||
| *.pyc | ||
| .coverage | ||
| .pytest_cache/ | ||
| *.egg-info/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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` | ||
|
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 | ||
| ``` | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.