Skip to content

feat(Ξ±-8 Phase A): ontology +5 horizontal types + graph_typed_filter module + flag#688

Merged
Hashevolution merged 1 commit into
mainfrom
feat/v0.4-alpha8-phase-a-ontology
Jun 2, 2026
Merged

feat(Ξ±-8 Phase A): ontology +5 horizontal types + graph_typed_filter module + flag#688
Hashevolution merged 1 commit into
mainfrom
feat/v0.4-alpha8-phase-a-ontology

Conversation

@Hashevolution
Copy link
Copy Markdown
Owner

Summary

Ξ±-8 implementation Phase A β€” opt-in typed entity filter that preserves the evidence-of-absence signal Ξ±-7 broke.

Design memo: `docs/design/v0.4-alpha-8-ontology-typed-filter.md` Β§1.5-1.6 + Β§2.4 R1-R5.

Diff stats

File Change Size
`core/ontology.py` +163 lines (4.9 KB β†’ 14.9 KB) under 20 KB gate βœ“
`core/graph_typed_filter.py` NEW (10.7 KB) under 20 KB gate βœ“
`tests/test_graph_typed_filter.py` NEW (33 tests) β€”

Ontology extensions

  • `ENTITY_TYPES` registry β€” 9 types (4 existing + 5 new horizontal: event/date/location/quantity/project)
  • 6 new relations: OCCURRED_AT / HAPPENED_ON / LOCATED_IN / INVOLVES / MEASURED_AS / WORKED_ON
  • ALLOWED_RELATIONS extended; LABEL_TO_TYPE Korean labels added
  • Helpers: is_active_entity_type / get_entity_type_info / list_active_entity_types
  • Self-test extended (4 existing + 6 new Ξ±-8 cases)

Mother-platform rule #1 compliance: all 5 new types horizontal. Deferred (regulation/transaction/recipe) per design memo Β§2.3.

Backward compat (Β§3.3): existing 931 wiki entities frontmatter unchanged; superset values; no migration needed.

graph_typed_filter module (R1-R5)

Rule Implementation
R1 Never silently drop type slot β€” empty rows emitted for query-relevant types
R2 "(none found in graph for this query)" explicit string
R3 Empty β‰  type-not-in-query (classifier identifies relevance)
R4 Order by intent ranking
R5 Cap ≀ 10 type slots; never truncate WITHIN slots

Public API: `is_typed_filter_disabled()`, `classify_query_intent(query)`, `group_entities_by_type(entities, query_types, cap)`, `format_typed_context(groups)`, `apply_typed_filter(query, entities, cap)`.

Polarity: `JAMES_DISABLE_TYPED_FILTER` env (disable-polarity, default OFF = filter ON when wired; unset/empty/"0"/"false" β†’ False, "1"/"true"/etc β†’ True).

Verification

```
$ python -m pytest tests/test_graph_typed_filter.py
33 passed, 4 warnings in 0.05s

$ python -m pytest tests/ -k "ontology or typed_filter or graph"
267 passed, 3213 deselected, 4 warnings in 1.04s

$ python -m ruff check core/ontology.py core/graph_typed_filter.py tests/test_graph_typed_filter.py
All checks passed!
```

Out of scope (Phase B-D)

  • Phase B: matrix cell `C_rag-ontology` + intent classifier wiring at `routes/query.py`
  • Phase C: N=3 baseline + 5-tier remeasurement
  • Phase D: closure analysis + `docs/ARCHITECTURE.md Β§5.7` typed filter section + acceptance test (multihop_rag null query + Ali poison_01/04)

Bench numbers

ν•΄λ‹Ή μ—†μŒ β€” Phase A λŠ” module + flag 만 쑴재. `routes/query.py` 톡합은 Phase B. Default μƒνƒœμ—μ„œ production /query/ path 변동 μ—†μŒ.

`Quality delta: exempt (label: code β€” A/B oracle infrastructure; production path unchanged, integration deferred to Phase B per design memo)`

πŸ€– Generated with Claude Code

…module + flag

Ξ±-8 implementation Phase A β€” opt-in typed entity filter that preserves
the evidence-of-absence signal Ξ±-7 broke. Design memo:
docs/design/v0.4-alpha-8-ontology-typed-filter.md Β§1.5-1.6 + Β§2.4 R1-R5.

## core/ontology.py (+4.9 KB β†’ 14.9 KB; under 20 KB gate)

- New `ENTITY_TYPES` registry β€” 9 types (4 existing + 5 new horizontal:
  event/date/location/quantity/project)
- 6 new relations: OCCURRED_AT / HAPPENED_ON / LOCATED_IN / INVOLVES /
  MEASURED_AS / WORKED_ON (with allowed_head/tail constraints)
- ALLOWED_RELATIONS extended (5 new entries + existing entries gain
  cross-type relations like LOCATED_IN for person/org)
- LABEL_TO_TYPE Korean labels for 6 new relations
- Helper functions: is_active_entity_type / get_entity_type_info /
  list_active_entity_types
- Self-test extended (existing 4-type cases + 6 new Ξ±-8 cases)

Mother-platform rule #1 compliance: all 5 new types horizontal (event /
date / location / quantity / project). Deferred types per design memo
Β§2.3: regulation (legal-leaning), transaction (finance/retail-leaning),
recipe (food-only, rejected).

Backward compat (Β§3.3): existing 931 wiki entities' frontmatter
unchanged; ALLOWED_RELATIONS keys remain present with superset values;
RELATION_TYPES additive only; no migration needed.

## core/graph_typed_filter.py (10.7 KB new; under 20 KB gate)

R1-R5 evidence-of-absence preservation rules from design memo Β§2.4:
- R1: Never silently drop a type slot β€” empty rows emitted for query-
  relevant types
- R2: Empty-type rows first-class β€” "(none found in graph for this query)"
  explicit string
- R3: Empty β‰  type-not-in-query β€” classifier output identifies relevant
  types
- R4: Order by query intent ranking
- R5: Cap total type slots ≀ 10 (default); never silently truncate WITHIN
  slots

Public API:
- is_typed_filter_disabled() β€” `JAMES_DISABLE_TYPED_FILTER` env flag
  (disable-polarity, default OFF = filter ON)
- classify_query_intent(query) β€” keyword heuristic β†’ ranked type list
  (7 intent buckets EN+KO; cheap deterministic per design memo Β§2.1)
- group_entities_by_type(entities, query_types, cap=10) β€” R1-R5 apply
- format_typed_context(groups) β€” render explicit `[Type]: ...` /
  `[Type]: (none found...)` string for LLM
- apply_typed_filter(query, entities, cap=10) β€” end-to-end convenience

## tests/test_graph_typed_filter.py (33 tests)

- Flag polarity (6 tests: unset/empty/0/false β†’ False; 1/true β†’ True)
- Intent classifier (10 tests: EN+KO + fallback + cap)
- R1-R5 grouping (9 tests: empty preserved / present flag / non-query
  surfaced / non-query empty omitted / order / cap / within-slot no
  truncation)
- Renderer format (5 tests)
- End-to-end acceptance smoke (2 tests: poison_01 analog + temporal
  null query both emit empty-slot rows)

## Verification

- 33/33 tests/test_graph_typed_filter.py pass
- 12/12 tests/test_ontology* pass (regression OK)
- 267/267 ontology+graph+typed_filter tests pass
- ruff F-class clean

## Out of scope (Phase B-D)

- Phase B: matrix cell `C_rag-ontology` + intent classifier wiring at
  routes/query.py
- Phase C: N=3 baseline + 5-tier remeasurement
- Phase D: closure analysis + ARCHITECTURE.md Β§5.7 + acceptance test
  (multihop null + Ali poison_01/04)

## Bench numbers

Default flag OFF (filter ON): module exists standalone but no wired
integration point in Phase A β€” production /query/ path unchanged.
Sector cell wiring is Phase B. Therefore no behavior change at this
stage, Quality Delta Card not applicable.

Quality delta: exempt (label: code β€” A/B oracle infrastructure;
production path unchanged, integration deferred to Phase B per design memo)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Hashevolution Hashevolution merged commit fcf343d into main Jun 2, 2026
4 checks passed
@Hashevolution Hashevolution deleted the feat/v0.4-alpha8-phase-a-ontology branch June 2, 2026 09:40
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant