Skip to content

week_1-1: Module C — Pydantic contracts + config loader#2

Open
PRAteek-singHWY wants to merge 26 commits into
mainfrom
gsocmodule_C_week_1_1
Open

week_1-1: Module C — Pydantic contracts + config loader#2
PRAteek-singHWY wants to merge 26 commits into
mainfrom
gsocmodule_C_week_1_1

Conversation

@PRAteek-singHWY

Copy link
Copy Markdown
Owner

What this PR is

This is the first of three planned PRs for Module C, Week 1 (May 25–31). It lands the boundary layer for the Librarian — the data contracts the module reads and writes, plus the test scaffolding that will keep us honest as the pipeline grows. There is no linking logic, no embeddings, no decisions in this PR; that comes in week_1-2 (eval harness + hub-firewall + scoring) and week_1-3 (real 277-row golden dataset). Per Spyros's guidance, W1 is contracts and tests before any pipeline code, so this PR is deliberately small and behaviour-neutral for OpenCRE proper.

Why this PR exists at all

Module C consumes a JSON envelope from Module B (Manshu) and emits two JSON envelopes — one to the OpenCRE graph and one to Module D's review queue. Those shapes are defined in RFC OWASP#734 (docs/owasp-graph/apis/schemas/*.json). If we start writing the C pipeline before pinning down the contracts in Python types, every later PR risks rework when Spyros's RFC settles. So W1's job is just:

  1. make those JSON shapes real Pydantic types,
  2. prove they actually match the RFC (not what a summary doc says), and
  3. wire up the CRE_LIBRARIAN_* config the later weeks will read.

That is exactly what this PR does.

What's in this PR, step by step

1. The librarian package skeleton

application/utils/librarian/ is a new module. Its __init__.py documents the three contract directions (B → C, C → graph, C → D) and pins the upstream RFC commit we're tracking (upstream/owasp-graph @ 2b143798) with the resync command, so any contributor can re-pull the canonical schemas if Spyros updates PR OWASP#734.

2. The v0.2.0 RFC contracts in schemas.py

Modeled directly from PR OWASP#734's JSON schemas, not from the master-guide summary:

  • `KnowledgeItem` — what Module B emits for one chunk. Full RFC envelope: `event_id`, `filtered_at`, `status ∈ {accepted, rejected, deferred}`, `source`, `locator`, a `content` block (`text`, `title_hint`, `keywords`, `language`), and a `filter` block whose `stages[]` records the regex/LLM pipeline plus scores. Conditional rules from the RFC's `allOf` block — `status=accepted` requires `content`, `status=rejected` requires `rejection` — are enforced as Pydantic `model_validator`s.
  • `LinkProposal` — C's auto-link output. `status` is fixed to `"linked"` (`Literal` const), `pipeline_run_id` and `update_detection` are required (the RFC says so), `links` must be non-empty, `additionalProperties: false`.
  • `ReviewItem` — C's human-review output. `status` fixed to `"review_required"`; `reason_code` is the 4-value enum from the RFC (`BELOW_THRESHOLD`, `NO_CANDIDATES`, `ADVERSARIAL_FLAG`, `UPDATE_AMBIGUOUS`).
  • Shared sub-models — `SourceRef` (with the conditional `type=github → repo + commit_sha`), `Locator` (with `kind=repo_path → path`, `kind=url|feed_item → url`), `KnowledgeSnapshot`, `RetrievalAudit`, `CreCandidate` (including `score_hybrid` for any future BM25 hybrid), `ProposedLink`, `UpdateDetection`.

Every required field, conditional rule, enum, and `additionalProperties: false` constraint from the canonical schemas is enforced.

3. Internal-only models (NOT part of the RFC)

  • `KnowledgeQueueItem` — a Pydantic mirror of Module B's `knowledge_queue` Postgres row, per master guide §1.2. At W8, C will read these rows and synthesize the RFC `KnowledgeItem` envelope from them. This is just an internal contract between B's SQL and C's Python.
  • `GoldenDatasetRow` — Pydantic model of the regression-harness row defined in `gsoc-notes/bonding/golden_dataset.schema.json`. The harness itself lands in `week_1-2`.

4. The drift guard — vendored canonical schemas + a round-trip test

The single biggest risk: my Pydantic models drift from Spyros's RFC and we don't notice until weeks later. The fix:

  • The 6 canonical RFC schemas are vendored verbatim under `application/utils/librarian/_rfc_schemas/`, pinned to a specific upstream SHA.
  • `schemas_test.py` dumps each Pydantic contract to JSON and validates it against the canonical schema using `jsonschema.Draft202012Validator` + a `referencing.Registry` that resolves `$ref`s by `$id`. If a Pydantic model ever produces something the RFC schema rejects (or vice versa), this test fails the build.
  • It also re-validates the literal `ReviewItem` example from `docs/owasp-graph/apis/module-c-librarian.md`, so we catch drift in the prose example too.

This is the guardrail that protects every later C PR from silently diverging.

5. The config loader

`config_loader.py` reads the 7 `CRE_LIBRARIAN_*` env vars into a frozen dataclass:

Env var Default
`CRE_LIBRARIAN_CROSSENCODER_MODEL` `cross-encoder/ms-marco-MiniLM-L-6-v2`
`CRE_LIBRARIAN_TOP_K_RETRIEVAL` `20`
`CRE_LIBRARIAN_TOP_K_RERANK` `5`
`CRE_LIBRARIAN_LINK_THRESHOLD` `0.8`
`CRE_LIBRARIAN_BATCH_SIZE` `32`
`CRE_LIBRARIAN_ECE_TARGET` `0.10`
`CRE_LIBRARIAN_CONFORMAL_ALPHA` `0.10`

Tests cover defaults, env overrides, frozen behaviour, and invalid-int handling.

6. Real B-SQL-row fixture

`fixtures/sample_knowledge_queue.jsonl` has 3 mock rows in the actual `knowledge_queue` column shape (`id`, `source_repo`, `source_path`, `source_commit_sha`, `text`, `confidence`, `llm_label`, `llm_reasoning`, `created_at`, `consumed_at`) — so future tests work against realistic input rather than a guess.

7. Pydantic pin

One-line change to `requirements.txt`: `pydantic>=2,<3` (was unpinned). This PR relies on Pydantic v2's `model_validator` and `ConfigDict`.

What is deliberately NOT in this PR

  • Hub-firewall, eval harness, scoring, knowledge-source stub → land in `week_1-2`.
  • The real 277-row `golden_dataset.json` → lands in `week_1-3` (derived from `standards_cache.sqlite`'s `cre_node_links`).
  • No edits to `config.py`, `cre.py`, `cre_main.py`, `db.py`, or any migration. Those are W3 (CLI wiring) and W8 (DB models / live B→C integration) per master-guide §8.2.
  • No retriever / embeddings / cross-encoder code. W3 onwards.

How to verify locally

```bash
python3 -m unittest discover -s application/tests/librarian -p '*_test.py' -t .
```
Expected: 31 passed. The suite covers the RFC round-trips (`LinkProposal`, `ReviewItem`, `KnowledgeItem` accepted + rejected, and the `module-c-librarian.md` example), all the conditional rules, `additionalProperties: false`, config defaults + overrides, and the internal `KnowledgeQueueItem` + `GoldenDatasetRow`.

Black-clean. No existing repo test affected (no production file is touched beyond the one-line pydantic pin).

Open question for mentors (does NOT block this PR)

Q-D — multi-link scoring rule. When a chunk maps to several CREs, what counts as "correct" in the regression harness? My proposed default (which lands in `week_1-2`): Jaccard ≥ 0.5 of the expected CRE set AND top-1 in the set. Confirmation appreciated at the Friday call — this blocks `week_1-2`'s merge, not this PR (there's no scoring code here yet).

Resyncing if the RFC changes

The vendored schemas are pinned to `upstream/owasp-graph @ 2b14379`. If Spyros pushes new commits to PR OWASP#734:
```bash
git fetch upstream owasp-graph
for f in link-proposal review-item knowledge-item proposed-link source-ref locator; do
git show upstream/owasp-graph:docs/owasp-graph/apis/schemas/$f.json \
> application/utils/librarian/_rfc_schemas/$f.json
done

update the SHA in application/utils/librarian/init.py, then re-run the tests

```
The drift test will surface any change that needs a Pydantic-side update.


Following the Slack-agreed convention: branch `gsocmodule_C_week_1_1` off `main` of the fork, PR title `week_1-N: ` with numbering for multiple PRs in a week. `week_1-2` (harness) and `week_1-3` (golden set) will follow.

PRAteek-singHWY and others added 26 commits February 28, 2026 17:48
* feat(myopencre): add initial MyOpenCRE page and CSV template download

* chore(osib): update OWASP name to Open Worldwide Application Security Project

* feat(myopencre): enable CSV download of all CREs

* refactor(csv-import): move CSV validation into spreadsheet parser

* style(csv): format files with black

* refactor(csv-import): move CSV validation into spreadsheet parser

* style(myopencre): move container spacing to SCSS

* refactor(myopencre): move CSV validation to parser and add noop import handling

* style(csv): format files with black
… safeguards (OWASP#685)

feat(myopencre): add CSV import preview and confirmation flow
* Fix : resolve navbar alignment on desktop and mobile

* reverted previous wrong changes and implemented correct changes
ui(myopencre): add inline help guide for CSV preparation
…ckend capability flag (OWASP#704)

feat(myopencre): gate frontend routes and nav behind capabilities API
)

* docs: add .env.example and document environment configuration

* feat: automatically load environment variables from `.env` for local development and update `.env.example` comments.

* style: Remove trailing whitespace from `load_dotenv()` call.
add graph debugging information to explorer

Signed-off-by: Mahaboobunnisa Md <mdshabbi885@gmail.com>
… gracefully (OWASP#776)

* Handle Redis connection errors in gap_analysis.py

Added error handling for Redis connection failure.

Signed-off-by: Rashmi Vemuri <rashmivemuri@gmail.com>

* Add service startup instructions for local development

Added instructions to start required services before running locally.

Signed-off-by: Rashmi Vemuri <rashmivemuri@gmail.com>

---------

Signed-off-by: Rashmi Vemuri <rashmivemuri@gmail.com>
OWASP#784)

feat: Apply general styling, text colors, and input background to the explorer page, with minor layout and selector refinements.
…age background (OWASP#768)

fix(frontend): scope overscroll handling without global dark background
* fix: improve explorer debug table mobile responsiveness

* fix: show debug label always, add tooltip, fix explorer text visibility
* Update CONTRIBUTING.md with contribution guidelines

Added guidelines for avoiding trivial UI issue reports and LLM-generated contributions. Emphasized the importance of quality over quantity in contributions and outlined expectations for pull requests.

Signed-off-by: Parth_Sohaney <130902651+Pa04rth@users.noreply.github.com>

* add language against the recent 'open ticket'-'submit low value pr' onslaught

---------

Signed-off-by: Parth_Sohaney <130902651+Pa04rth@users.noreply.github.com>
Co-authored-by: Spyros <morfeas3000@gmail.com>
* fix: clean up misc_tools_parser.py

- removed unused NamedTuple import
- replaced xmlrpc.client.boolean with built-in bool
- fixed typo in parser name (miscelaneous -> miscellaneous)
- standardized logging to use module-level logger instead of root logging
- replaced print() with logger.info() for consistency
- added proper type annotations (List[defs.Tool]) to parse_tool

* fix: address review feedback on misc_tools_parser.py

- dry_run early return to avoid UnboundLocalError on repo.working_dir
- guard against empty tool_entries in parse() to avoid IndexError
- better error message that includes readme path and repo url
…SP#828)

* Collapse linked sources if more than 5 entries (fixes OWASP#283)

* Fix uneven spacing and add consistent bottom margin to link containers

Signed-off-by: rashmivemuri <rashmivemuri@gmail.com>

---------

Signed-off-by: rashmivemuri <rashmivemuri@gmail.com>
Improved SearchBar UI - sharpened icon, updated styles

Signed-off-by: Parth_Sohaney <130902651+Pa04rth@users.noreply.github.com>
Co-authored-by: Parth_Sohaney <130902651+Pa04rth@users.noreply.github.com>
…tent (OWASP#777)

* Improved RAG prompt to stop it referring to the resource

* Improve RAG prompt to prevent it always ignoring retrieved info
* test: rename duplicated db and oscal test cases

* Fix duplicate test names in DB and OSCAL tests
This PR improves topic-page clarity by reducing CRE jargon, clarifying hierarchy wording, and making topic navigation easier to scan.
Scope is frontend-only; no backend schema or migration changes.

Change Details + Manual Verification
1) Topic page basic cleanup
This update simplifies topic-page labeling so the page is easier to read at a glance.
CRE-prefixed naming was removed from child rows, and section wording now uses Requirements.
The topic identifier presentation was also cleaned up for consistency.

Verification:

Subheading: CRE: 546-564 -> ID: 546-564
Child rows: CRE : 028-727 : CSRF protection -> CSRF protection
Section title: Which contains CREs -> Which contains Requirements
Before: image
After: image
2) Wording + related behavior + topic naming
Relationship labels were rewritten in clearer language and aligned to hierarchy meaning.
CRE-centric phrasing was replaced with Requirements where applicable.
Related topic nodes now collapse by default to reduce visual noise on initial load.

Verification:

Link heading: Which is linked to sources -> Which refers to sources
Parent heading: Which is part of CREs -> Which is child of Requirements
Related topic nodes are collapsed by default
Topic line naming no longer shows CRE : xxx-xxx prefix
Before: image
After: image
3) Block order + visual clarity
Link-related blocks were reordered so external/reference context appears before contained requirements.
This improves reading flow and makes the relationship hierarchy clearer.
Styling was adjusted with stronger indentation/border cues for easier section scanning.

Verification:

Block order is now:
refers to sources
contains Requirements
Visual block separation/indentation is stronger on local build
Before: image
After: image
4) Standard-page wording
Standard-page relationship text was updated to match the same terminology cleanup used on topic pages.
The change keeps wording consistent across page types and improves readability.

Verification:

Heading text: Which is linked from CREs -> Which is referenced by Requirements
Before: image
After: image
5) Explorer list cleanup
Explorer topic entries were cleaned to remove ID-prefix style from visible topic text.
This makes the list easier to skim and keeps the focus on topic names.

Verification:

Topic entries no longer show prefixes like 546-564:
Topic text shows clean names only
Before: image
After: image
Notes
tags: line is not explicitly present in the tested pages; no direct removal hook was required in this patch.
This PR remains focused on Clean up topic page and make more clear OWASP#186 wording and topic-page clarity behavior only.
* Improved RAG prompt to stop it referring to the resource

* Improve RAG prompt to prevent it always ignoring retrieved info

* Furhter improve RAG prompt to let it decide if knowledge is relevant

---------

Signed-off-by: Spyros <northdpole@users.noreply.github.com>
Co-authored-by: Spyros <northdpole@users.noreply.github.com>
Adds the librarian package boundary with the v0.2.0 RFC OWASP#734 contracts:
KnowledgeItem (full envelope with status / content / filter / rejection),
LinkProposal (status='linked', required pipeline_run_id + update_detection,
extra="forbid"), ReviewItem (status='review_required'), plus the shared
sub-models SourceRef / Locator / KnowledgeSnapshot / RetrievalAudit /
CreCandidate / ProposedLink / UpdateDetection. Conditional rules from each
schema's allOf block are enforced as Pydantic validators.

Also adds the internal KnowledgeQueueItem (mirror of Module B's SQL row per
master guide §1.2), the internal GoldenDatasetRow (harness only), the
CRE_LIBRARIAN_* env loader, and the canonical RFC JSON schemas vendored
verbatim under _rfc_schemas/ (pinned to upstream/owasp-graph @ 2b14379).

Pins pydantic to >=2,<3 in requirements.txt so contract shape is stable
across contributor envs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the test suite for week_1-1:

- schemas_test.py: every RFC envelope (KnowledgeItem accepted+rejected,
  LinkProposal, ReviewItem) is dumped from its Pydantic model and validated
  against the vendored canonical JSON schema using a referencing.Registry
  that resolves $refs across source-ref / locator / proposed-link. Also
  re-validates the literal ReviewItem example from
  docs/owasp-graph/apis/module-c-librarian.md and exercises the conditional
  rules (github→repo+sha, kind→path|url, accepted→content, rejected→
  rejection, schema_version pattern, links min-length, extra-field forbid).
- config_loader_test.py: defaults when env unset, env overrides apply,
  config is frozen, bad ints raise.
- fixtures/sample_knowledge_queue.jsonl: 3 mock rows in the real
  knowledge_queue SQL-row shape (id, source_repo, source_path,
  source_commit_sha, text, confidence, llm_label, llm_reasoning,
  created_at, consumed_at).

31/31 tests green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.