keble-idea 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. keble_idea-0.3.0/.gitattributes +2 -0
  2. keble_idea-0.3.0/.gitignore +41 -0
  3. keble_idea-0.3.0/AGENTS.md +29 -0
  4. keble_idea-0.3.0/AiAgentChangesLogs.md +296 -0
  5. keble_idea-0.3.0/CODE_GUIDELINES.md +87 -0
  6. keble_idea-0.3.0/PKG-INFO +187 -0
  7. keble_idea-0.3.0/README.md +177 -0
  8. keble_idea-0.3.0/pyproject.toml +55 -0
  9. keble_idea-0.3.0/src/keble_idea/__init__.py +66 -0
  10. keble_idea-0.3.0/src/keble_idea/application/__init__.py +1 -0
  11. keble_idea-0.3.0/src/keble_idea/application/lifecycle.py +251 -0
  12. keble_idea-0.3.0/src/keble_idea/application/ports.py +393 -0
  13. keble_idea-0.3.0/src/keble_idea/application/publication.py +35 -0
  14. keble_idea-0.3.0/src/keble_idea/application/services.py +713 -0
  15. keble_idea-0.3.0/src/keble_idea/domain/__init__.py +1 -0
  16. keble_idea-0.3.0/src/keble_idea/domain/base.py +134 -0
  17. keble_idea-0.3.0/src/keble_idea/domain/concept.py +143 -0
  18. keble_idea-0.3.0/src/keble_idea/domain/content.py +340 -0
  19. keble_idea-0.3.0/src/keble_idea/domain/errors.py +117 -0
  20. keble_idea-0.3.0/src/keble_idea/domain/generation.py +145 -0
  21. keble_idea-0.3.0/src/keble_idea/domain/idea.py +315 -0
  22. keble_idea-0.3.0/src/keble_idea/domain/job.py +799 -0
  23. keble_idea-0.3.0/src/keble_idea/domain/relationship.py +155 -0
  24. keble_idea-0.3.0/src/keble_idea/domain/search.py +288 -0
  25. keble_idea-0.3.0/src/keble_idea/domain/source.py +71 -0
  26. keble_idea-0.3.0/src/keble_idea/processors/__init__.py +1 -0
  27. keble_idea-0.3.0/src/keble_idea/processors/concepts.py +88 -0
  28. keble_idea-0.3.0/src/keble_idea/processors/confidence.py +85 -0
  29. keble_idea-0.3.0/src/keble_idea/processors/generations.py +66 -0
  30. keble_idea-0.3.0/src/keble_idea/processors/identity.py +78 -0
  31. keble_idea-0.3.0/src/keble_idea/processors/ranking.py +48 -0
  32. keble_idea-0.3.0/src/keble_idea/processors/relationships.py +116 -0
  33. keble_idea-0.3.0/src/keble_idea/testing/__init__.py +13 -0
  34. keble_idea-0.3.0/src/keble_idea/testing/repositories.py +353 -0
  35. keble_idea-0.3.0/tests/__init__.py +1 -0
  36. keble_idea-0.3.0/tests/contract/test_architecture_boundaries.py +97 -0
  37. keble_idea-0.3.0/tests/helpers.py +138 -0
  38. keble_idea-0.3.0/tests/unit/application/test_concept_alias_service.py +79 -0
  39. keble_idea-0.3.0/tests/unit/application/test_extraction_service.py +218 -0
  40. keble_idea-0.3.0/tests/unit/application/test_lifecycle_services.py +300 -0
  41. keble_idea-0.3.0/tests/unit/application/test_recovery_profile_store.py +103 -0
  42. keble_idea-0.3.0/tests/unit/application/test_search_service.py +420 -0
  43. keble_idea-0.3.0/tests/unit/domain/test_commerce_content_contracts.py +104 -0
  44. keble_idea-0.3.0/tests/unit/domain/test_job_failure_recovery.py +403 -0
  45. keble_idea-0.3.0/tests/unit/domain/test_lifecycle_contracts.py +241 -0
  46. keble_idea-0.3.0/tests/unit/domain/test_schema_contracts.py +166 -0
  47. keble_idea-0.3.0/tests/unit/processors/test_identity_confidence_generation.py +73 -0
  48. keble_idea-0.3.0/tests/unit/processors/test_relationship_evolution.py +66 -0
  49. keble_idea-0.3.0/uv.lock +1399 -0
@@ -0,0 +1,2 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
@@ -0,0 +1,41 @@
1
+ # Generated by Cargo
2
+ # will have compiled files and executables
3
+ debug/
4
+ target/
5
+ cert/
6
+
7
+ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
8
+ # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
9
+ Cargo.lock
10
+
11
+ # These are backup files generated by rustfmt
12
+ **/*.rs.bk
13
+
14
+ # MSVC Windows builds of rustc generate these, which store debugging information
15
+ *.pdb
16
+ *__ignored__*
17
+
18
+ *.env
19
+ *.DS_Store
20
+ **/.DS_Store
21
+
22
+ .vscode
23
+ .idea
24
+
25
+ *.crt
26
+
27
+ uploads/
28
+ !strapi-v5/public/uploads/
29
+ !strapi-v5/public/uploads/.gitkeep
30
+ test/
31
+ resources/
32
+ Brewfile
33
+ qdrant/
34
+ *.pyc
35
+ **.pyc.*
36
+ */traefik/certs
37
+ */traefik/certs/*
38
+ gcp.json
39
+ .history
40
+
41
+ prod.env.*
@@ -0,0 +1,29 @@
1
+ # Keble Idea Agent Rules
2
+
3
+ - Read the umbrella `AGENTS.md`, `ENGINEERING_PRINCIPLES.md`, and
4
+ `TESTING_GUIDELINE.md` before changing this repo.
5
+ - Keep `domain/` and `application/` independent from raw providers, FastAPI,
6
+ Celery, RabbitMQ, MongoDB, Redis, Qdrant, and Neo4j implementations.
7
+ - Preserve one canonical schema/protocol/use case for each behavior. Remove
8
+ replaced contracts instead of retaining compatibility aliases.
9
+ - Do not persist LOW candidate stories, concepts, evidence, scores, or tags.
10
+ - Do not add idea/story vector collections or idea graph nodes.
11
+ - Do not use `try/except`, `getattr`, `setattr`, in-function imports, pass-only
12
+ tests, test skips, broad scans, offset pagination, or total-count queries.
13
+ - Every changed function, class, and schema needs a docstring with steps where
14
+ useful and a concise `Side effects if changes:` note for downstream contracts.
15
+ - Tests use canonical layer folders and the umbrella marker vocabulary.
16
+ - Update `README.md`, `CODE_GUIDELINES.md`, and `AiAgentChangesLogs.md` when a
17
+ completed milestone changes behavior or test proof.
18
+ - Persist one `JobFailureSnapshot`; never restore loose `error_code`,
19
+ `retry_classification`, raw response bags, or provider exception types.
20
+ - Recovery profiles are append-only. Every job stores the complete submitted
21
+ snapshot, automatic retry preserves it, and manual retry adopts the active
22
+ profile only through an explicit command flag.
23
+ - Retry timestamps derive from immutable failure observation plus deterministic
24
+ envelope/attempt jitter. Re-evaluation must not move a schedule.
25
+
26
+ Side effects if changes:
27
+
28
+ - Platform queue transitions, Mongo indexes, provider gates, incidents,
29
+ financial attempts, generated APIs, and frontend labels consume these rules.
@@ -0,0 +1,296 @@
1
+ # AI Agent Changes Logs
2
+
3
+ ## 2026-07-13 16:50 CST
4
+ State: `refactor/financial-usage-receipts`; physical-attempt identity checkpoint,
5
+ no version, tag, release, or main merge authorized.
6
+
7
+ zma:
8
+ - Execute the complete financial-accuracy and 100K-ingestion plan, preserving
9
+ provider retries while keeping broker replay idempotent.
10
+
11
+ Ai:
12
+ - Added `EnvelopeExecutionIdentity` and propagated the atomically leased
13
+ envelope key/attempt number through extraction and relationship protocols.
14
+ - Updated canonical services and tests so platform adapters can create a new
15
+ spend identity for each physical retry without duplicating one lease attempt.
16
+
17
+ ## 2026-07-12 23:01 CST
18
+ State: `feature/saas-admin-console`; owner accepted the integrated Data Platform
19
+ review and authorized fast-forward integration to current remote main. No
20
+ version, tag, or release is requested.
21
+
22
+ zma: accepted for now; merge the verified work to main.
23
+
24
+ Ai: refreshed origin and proved the lifecycle-contract branch is a strict
25
+ fast-forward of `origin/main`; the standalone correction and foundation work are
26
+ already ancestors. This records authorization before the non-force main update.
27
+
28
+ ## 2026-07-12 15:40 CST
29
+ State: `feature/saas-admin-console`; canonical schema-version-2 operator
30
+ lifecycle contracts land ahead of the platform SaaS admin console. No version
31
+ bump, tag, release, or main merge.
32
+
33
+ zma: Redesign the data platform + Keble Ideas admin frontend per
34
+ `docs/plans/REWORK_DATA_PLATFORM_LAYOUT.md` — replace the monolithic developer
35
+ console with a protected SaaS operator app (Truth-backed auth, typed lifecycle
36
+ commands, controlled purge). This repo owns the canonical lifecycle schemas.
37
+
38
+ Ai: Added schema-version-2 lifecycle contracts: `ContentLifecycle`
39
+ (ACTIVE/ARCHIVED/PURGING) with `lifecycle` + `archived_at` on `ContentBody`,
40
+ `IdeaLifecycle` (ACTIVE/RETIRED/PURGING) with `lifecycle` + `retired_at` on
41
+ `IdeaBody`, both with timestamp-consistency validators and finite
42
+ `*_LIFECYCLE_TRANSITIONS` maps (PURGING terminal). New content/idea records
43
+ default `schema_version=2` (`CONTENT_SCHEMA_VERSION` / `IDEA_SCHEMA_VERSION`);
44
+ stored v1 rows still validate via ACTIVE defaults until the platform backfill
45
+ migration stamps them. Added `IdeaJobStatus.CANCELLED` +
46
+ `IdeaJobType.PURGE` and canonical `TERMINAL_JOB_STATUSES` /
47
+ `CANCELLABLE_JOB_STATUSES` sets. Added typed `LifecycleTransitionError`
48
+ (`IdeaErrorCode.INVALID_LIFECYCLE_TRANSITION`) and the shared
49
+ `assert_lifecycle_transition` guard in `domain/errors.py`. New
50
+ `tests/unit/domain/test_lifecycle_contracts.py` (13 tests) plus `build_idea`
51
+ helper; suite 40 passed, pyright clean.
52
+
53
+ ## 2026-07-12 10:10 CST
54
+ State: `feature/idea-foundation`; the provider-neutral video payload now retains
55
+ OCR-only and unknown-language observations without claiming they are English.
56
+
57
+ zma:
58
+
59
+ - Continue the complete Stand Out media integration with real OCR/ASR models,
60
+ preserve original content, and proceed until human quality inspection.
61
+
62
+ Ai:
63
+
64
+ - Added `VideoContentPayload.ocr_text_original` beside the existing normalized
65
+ English field. This prevents successful OCR from disappearing when ASR is
66
+ absent or reports a non-English language, while keeping `ocr_text_en`
67
+ semantically strict.
68
+ - Added contract coverage for camel-case wire serialization and the rule that
69
+ original OCR does not implicitly populate English evidence.
70
+
71
+ ## 2026-07-11 15:51 CST
72
+ State: `feature/idea-foundation` implements the provider-neutral foundation and
73
+ portable vertical contracts from `docs/plans/COMPLETE_STAND_OUT_BY_CX.md`; no
74
+ version bump, tag, or release label is authorized yet.
75
+
76
+ zma:
77
+
78
+ - Implement the complete Stand Out plan while avoiding concurrent work in
79
+ `keble-data-infra`, `keble-idea`, and `keble-data-platform` checkouts.
80
+ - Keep idea provider-neutral, strongly typed, ACID-aware, concept-vector-only,
81
+ reversible, bounded, and executable by later workers without hidden context.
82
+
83
+ Ai:
84
+
85
+ - Added strict content, evidence, receipt, idea, eight-facet concept, scalar
86
+ posting, relationship, generation, queue ledger, and search contracts.
87
+ - Added deterministic content/record identities, exact extraction batch
88
+ correction, composite confidence and LOW discard, idempotent publication,
89
+ reversible PURPOSE aliases, neighborhood hysteresis, invalidation planning,
90
+ and concept-first cursor search application services.
91
+ - Added reusable portable in-memory adapters and 21 unit/contract tests covering
92
+ architecture boundaries, receipts, identities, duplicate delivery, aliases,
93
+ reruns, search sessions, and relationship retirement.
94
+ - Verified portable pytest (21 passed), strict pyright (0 errors), and package
95
+ sdist/wheel build under Python 3.13.12. The prescribed
96
+ `keble-2.1.0-3.13` conda environment is not installed on this host, so proof
97
+ uses the repo-local `uv` Python 3.13 environment.
98
+
99
+ ## 2026-07-11 16:30 CST
100
+ State: `feature/idea-foundation` generated-client contract correction before
101
+ platform frontend composition; no version/tag/release change.
102
+
103
+ zma: Implement the Stand Out plan through the typed platform and generated client.
104
+
105
+ Ai: Kept `ideaKey` in the API search item for detail navigation while leaving
106
+ display suppression to the frontend, and bound cursors to expiry plus the full
107
+ session generation/profile identity hash so a valid cursor cannot cross a
108
+ different frontier contract.
109
+
110
+ ## 2026-07-11 16:38 CST
111
+ State: `feature/idea-foundation` extraction usage contract aligned with the
112
+ platform PydanticAI runtime; no version/tag/release change.
113
+
114
+ zma: Implement the approved Stand Out plan through durable workers and cost diagnostics.
115
+
116
+ Ai: Changed the extractor port to return its typed batch together with exact
117
+ per-content provider usage. The canonical extraction service now accumulates
118
+ application-level correction usage before writing receipts, preventing guessed,
119
+ zero, or double-counted token/latency facts.
120
+
121
+ ## 2026-07-11 17:05 CST
122
+ State: `feature/idea-foundation` extended through immutable lifecycle and
123
+ relationship coverage contracts; no version/tag/release change.
124
+
125
+ zma: Continue implementing the complete Stand Out plan after rough human review,
126
+ preserving review traces and stopping only at a human test or inspection gate.
127
+
128
+ Ai: Added compare-and-swap generation cutover/rollback contracts, exact coverage
129
+ stamps, retention and resumable migration schemas, typed relationship candidates,
130
+ null-valid inference, deterministic accepted edge publication, and bounded alias
131
+ posting compaction. Added lifecycle tests proving no-relation coverage, accepted
132
+ edge generation identity, verified-only cutover, and rollback. Verified 24 portable
133
+ tests, strict pyright, and package builds under the repo-local Python 3.13 runtime.
134
+
135
+ ## 2026-07-11 17:14 CST
136
+ State: `feature/idea-foundation` external-safe artifact/auth failure vocabulary;
137
+ no version/tag/release change.
138
+
139
+ zma: Continue the complete Stand Out implementation through platform uploads and
140
+ external surfaces.
141
+
142
+ Ai: Added stable artifact-integrity/readiness, API-key, scope, and rate-limit error
143
+ codes so REST and MCP adapters can redact infrastructure failures while preserving
144
+ exact client behavior.
145
+
146
+ ## 2026-07-11 18:02 CST
147
+ State: `feature/idea-foundation` queue routing contract corrected before worker
148
+ composition; no version/tag/release change.
149
+
150
+ zma: Continue implementing the complete Stand Out worker and relationship flow.
151
+
152
+ Ai: Added a distinct `INFER_RELATIONSHIP` workload identity so typed model
153
+ inference cannot collide with `PROJECT_RELATIONSHIP`, which remains the derived
154
+ Neo4j projection job. This preserves one behavior per canonical queue contract.
155
+
156
+ ## 2026-07-11 18:34 CST
157
+ State: `feature/idea-foundation` reversible alias-posting compaction contract;
158
+ no version/tag/release change.
159
+
160
+ zma: Continue the complete Stand Out implementation until live human gates.
161
+
162
+ Ai: Added explicit `origin_concept_key` identity for derived canonical alias
163
+ postings, a compound uniqueness contract, and bounded clear behavior. Compaction
164
+ can now accelerate merged reads while unmerge deletes only derived rows and
165
+ preserves every original posting.
166
+
167
+ ## 2026-07-11 18:40 CST
168
+ State: `feature/idea-foundation` exact neighborhood evolution contract; no
169
+ version, tag, release label, or main merge.
170
+
171
+ zma: Continue the CX plan while the raw-provider repos remain owned by another
172
+ worker, and stop only at live human verification.
173
+
174
+ Ai: Replaced key-only relationship coverage with bounded typed neighbor
175
+ summaries carrying exact similarity, and stamped the configured consecutive
176
+ absence threshold. This gives platform persistence enough canonical evidence to
177
+ rotate current/previous neighborhoods and retire semantic-only edges with
178
+ hysteresis after revectoring instead of churning on one missing sweep. Verified
179
+ 24 tests, strict pyright, and package builds.
180
+
181
+ ## 2026-07-11 18:45 CST
182
+ State: `feature/idea-foundation` generation-idempotent relationship absence
183
+ tracking; no release metadata or main merge.
184
+
185
+ zma: Continue autonomous self-evolution implementation before human gates.
186
+
187
+ Ai: Added the last applied absence-neighborhood generation to canonical
188
+ relationship state. Outer Mongo adapters can now increment an exited edge at
189
+ most once per generation even when both endpoint coverage jobs observe the same
190
+ exit, preventing premature retirement from duplicate/symmetric sweeps.
191
+
192
+ ## 2026-07-11 20:51 CST
193
+ State: `fix/standalone-concept-model-retry` aligns model correction with the
194
+ canonical standalone-concept policy; no version/tag/release/main merge.
195
+
196
+ zma: Complete the live Amazon-to-idea vertical robustly and keep strict concept quality.
197
+
198
+ Ai: Added the non-raising `standalone_concept_error` contract and made the
199
+ publication validator delegate to it. Platform model adapters can now issue one
200
+ typed `ModelRetry` for generic or provider-like facets without catching errors,
201
+ repairing output, or duplicating the domain policy.
202
+
203
+ ## 2026-07-12 01:49 CST
204
+ State: `feature/idea-foundation` resumable migration identity contract; no
205
+ version, tag, or release metadata.
206
+
207
+ zma: Finish and reconcile the complete Stand Out plan, including comprehensive
208
+ real-database tests and merge verified work to main.
209
+
210
+ Ai: Strengthened `MigrationCheckpoint` with a named migration, canonical
211
+ collection owner, integer target schema version, and stable-key progress. This
212
+ lets the platform run bounded Mongo migration jobs without startup-time corpus
213
+ rewrites or ambiguous string versions. Added schema validation coverage and
214
+ documented the contract.
215
+
216
+ ## 2026-07-13 04:30
217
+ State: branch `feature/search-media-projection` (9f51c06) pushed; consumed by keble-data-platform via rev pin; NOT merged to main (train order: merge after the platform branch lands).
218
+
219
+ zma (via /goal, STAND_OUT_IMPROVE1): public idea search must show the idea WITH its image/video and type-specific metadata.
220
+
221
+ Ai: domain/search.py gains SearchMediaKind + IdeaSearchMedia (payload-owned derivation: PRODUCT first model-ready image, VIDEO original + first key-frame poster + duration, IMAGE normalized variant) + IdeaSearchSourceSummary (PRODUCT title/price, WEB_PAGE title); both ride IdeaSearchItem as wire-compatible optional fields. IdeaSearchService gains SearchContentReaderProtocol (application/ports.py) and hydrates media per page from ONE batched content read; InMemoryIdeaStore implements the port (contents dict + aget_contents). README notes images as a critical asset. 42 tests, pyright 0.
222
+
223
+ ## 2026-07-13 15:35 CST
224
+ State: `refactor/financial-usage-receipts`; provider-neutral receipt cleanup,
225
+ verified locally; no version, tag, release, or main merge.
226
+
227
+ zma: Execute the financial-accuracy and 100K-ingestion plan; remove duplicate
228
+ monetary truth from `keble-idea` while retaining strong usage contracts.
229
+
230
+ Ai: Removed `ProcessingUsage.cost_micros`, introduced receipt schema version 2,
231
+ and kept corrective-run merging limited to measured token/image/duration units.
232
+ Platform `CostFact` and `CostAllocation` are now the only intended monetary
233
+ owners. Added contract/unit guards, updated README, and verified 43 tests,
234
+ strict pyright, wheel, and sdist.
235
+
236
+ ## 2026-07-13 20:31 CST
237
+ State: `refactor/financial-usage-receipts`; Stage-B scheduling contract update,
238
+ no version, tag, publication, or main merge.
239
+
240
+ zma: Execute the financial-accuracy and 100K-ingestion plan, including bounded,
241
+ deduplicated, prioritized relationship work and comprehensive tests.
242
+
243
+ Ai: Added bounded provider-neutral relationship priority score/time fields to
244
+ canonical concepts. Platform publication can now project idempotent posting
245
+ quality and recency without changing concept identity, letting the graph queue
246
+ prioritize high-value/recent concepts while Stage A remains independent.
247
+
248
+ ## 2026-07-14 00:50 CST
249
+ State: `refactor/financial-usage-receipts`; queue-timing contract completion;
250
+ no version, tag, or publication.
251
+
252
+ zma: Complete the financial-accuracy and 100K-ingestion plan, including honest
253
+ queue/provider/elapsed timing and comprehensive tests.
254
+
255
+ Ai: Extended the existing provider-neutral `EnvelopeExecutionIdentity` with
256
+ optional chronological queued/leased timestamps. Platform adapters can now
257
+ copy durable queue timing into financial attempts without adding provider or
258
+ pricing ownership to Keble Idea. Added schema validation, README/guideline
259
+ documentation, and verified 45 tests plus Ruff and strict Pyright.
260
+
261
+ ## 2026-07-14 18:50 CST
262
+ State: `feature/trending-commerce-discovery`; package release candidate 0.2.0.
263
+
264
+ zma:
265
+ - Add first-class Amazon and TikTok trending ingestion without fitting creators,
266
+ sellers, or videos into product schemas.
267
+ - Preserve strong provider-neutral types, durable media identity, safe search
268
+ projections, comprehensive tests, and immutable downstream dependency pins.
269
+
270
+ Ai:
271
+ - Added distinct creator/seller profile and short-video content payloads while
272
+ retaining the existing product contract for product boards.
273
+ - Projected acquired profile images, video thumbnails, and safe display titles
274
+ into search without persisting provider names or transient playback URLs.
275
+ - Expanded content-kind filtering, added validation/projection tests, documented
276
+ the conversion boundary, and prepared the 0.2.0 contract release.
277
+
278
+ ## 2026-07-15 10:04 CST
279
+ State: `feature/durable-job-failures`; Idea 0.3.0 canonical failure/recovery
280
+ checkpoint, pending Platform adapter proof and the cross-repo release train.
281
+
282
+ zma:
283
+ - Execute the complete universal provider-failure plan with durable delays,
284
+ payment/quota evidence, full mocks/live tests, and all prior work on `main`.
285
+
286
+ Ai:
287
+ - Replaced loose queue `error_code`/`retry_classification` fields with one frozen
288
+ `JobFailureSnapshot`, sanitized physical usage/capacity evidence, and an XOR
289
+ processor result; added resumable `BLOCKED` state.
290
+ - Added immutable versioned recovery profiles, revision-guarded active pointer,
291
+ required per-job snapshot/attempt/deadline, stable deterministic retry timing,
292
+ excessive-hint blocking, and finite retry/block/dead-letter decisions.
293
+ - Added the reference profile repository protocol/in-memory CAS implementation,
294
+ bounded index shapes, public exports, README/agent/code guidance, and focused
295
+ contract coverage. Portable suite and strict Pyright currently pass; real
296
+ Mongo proof belongs to the Platform adapter phase and remains open.
@@ -0,0 +1,87 @@
1
+ # Keble Idea Code Guidelines
2
+
3
+ ## Ownership
4
+
5
+ The package owns semantic/domain contracts and caller-owned protocols. The
6
+ platform owns concrete infrastructure and provider conversions. Dependency
7
+ direction is checked through AST architecture tests.
8
+
9
+ ## Typed conversion flow
10
+
11
+ Use one explicit conversion chain:
12
+
13
+ ```text
14
+ platform source DTO -> ContentMongoObject -> ExtractionService
15
+ -> ContentPublication -> platform persistence adapter
16
+ ```
17
+
18
+ AI output must remain separate from persisted identity and audit fields.
19
+ Prompt fields and output schemas match exactly. Stable keys are internal
20
+ identity; display names are UX only.
21
+
22
+ ## Persistence and projections
23
+
24
+ Mongo mutations use deterministic keys, unique indexes, optimistic revisions,
25
+ and single-document atomic transitions. Multi-document work is a resumable
26
+ saga. Qdrant and Neo4j are derived projections repaired from Mongo truth.
27
+
28
+ ## Search
29
+
30
+ Search Qdrant concepts, expand Neo4j to depth at most two, resolve aliases,
31
+ read scalar postings through the compound ESR index, hydrate bounded Mongo
32
+ ideas, and freeze the ranked frontier in a Redis TTL session. Never add corpus
33
+ counts, offset paging, story-array scans, or unbounded graph queries.
34
+
35
+ ## Commerce content boundaries
36
+
37
+ Keep commerce resource kinds structurally distinct after provider conversion:
38
+ products use `ProductContentPayload`, creators and sellers use
39
+ `CommerceProfileContentPayload` plus `CommerceProfileType`, and ranked videos
40
+ use `ShortVideoContentPayload`. Do not fit profiles or videos into product
41
+ fields, persist transient playback URLs, or put provider-specific response bags
42
+ into the idea-owned schemas. The platform owns raw-provider conversion and
43
+ artifact acquisition before constructing these payloads.
44
+
45
+ ## Queue execution evidence
46
+
47
+ Keep logical envelope identity, physical attempt number, original admission
48
+ time, and physical lease time together in `EnvelopeExecutionIdentity`.
49
+ Provider packages consume this provider-neutral contract; they must not infer
50
+ queue wait from model duration or introduce pricing/provider fields here.
51
+
52
+ ## Failure and recovery ownership
53
+
54
+ Persist one immutable `JobFailureSnapshot` with optional sanitized
55
+ `UpstreamFailureEvidence`. Idea owns the job/recovery shape; Data Infra owns its
56
+ wire failure and Platform owns conversion, durable scheduling, gates, incidents,
57
+ and infrastructure. Never import Data Infra/provider exception types into this
58
+ package or preserve parallel loose error strings.
59
+
60
+ Every envelope snapshots an append-only recovery profile, attempt limit, and
61
+ deadline. Use `recovery_decision_for_failure` for the only retry/block/dead-
62
+ letter decision and `retry_at_for_failure` for stable deterministic timing.
63
+ Excessive provider hints block rather than retrying early. Payment requires
64
+ reviewed billing/account evidence; transport status and capacity alone do not
65
+ qualify.
66
+
67
+ Side effects if changes:
68
+
69
+ - queue Mongo updates must validate the entire envelope after every transition;
70
+ - profile activation changes only future admissions unless manual retry opts in;
71
+ - failed physical usage remains exact or explicitly billing unknown.
72
+
73
+ ## Generations and relationship evolution
74
+
75
+ Treat generation specifications as immutable records. Activate only verified
76
+ generations through a compare-and-swap pointer that retains one rollback-safe
77
+ generation. Stamp derived coverage with exact dependency generations rather
78
+ than a boolean. A typed null relationship is a completed inference result, and
79
+ posting compaction must remain bounded, resumable, and unnecessary for correct
80
+ query-time alias resolution.
81
+
82
+ ## Side-effect notes
83
+
84
+ Every changed public schema, protocol, service, and processor documents the
85
+ downstream adapters, workers, projections, API/client, or tests affected by a
86
+ contract change. Preserve human `reviewed` and `read` markers on untouched
87
+ blocks.
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.4
2
+ Name: keble-idea
3
+ Version: 0.3.0
4
+ Summary: Provider-neutral idea extraction, concept graph, generation, and search contracts.
5
+ Author-email: zma <bob0103779@gmail.com>
6
+ Requires-Python: >=3.13
7
+ Requires-Dist: keble-helpers<2,>=1.52.2
8
+ Requires-Dist: pydantic<3.0.0,>=2.10.0
9
+ Description-Content-Type: text/markdown
10
+
11
+ # Keble Idea
12
+
13
+ `keble-idea` owns the provider-neutral contracts and application behavior for
14
+ public content snapshots, standout ideas, semantic concepts, relationships,
15
+ immutable generations, durable work ledgers, and concept-first hybrid search.
16
+
17
+ It deliberately does not import FastAPI, Celery, MongoDB, Redis, Qdrant,
18
+ Neo4j, raw providers, or `keble-data-infra`. The host application implements
19
+ the protocols under `keble_idea.application.ports` and converts raw source
20
+ responses into idea-owned schemas at its outer boundary.
21
+
22
+ Version 0.3.0 adds the canonical persisted job-failure and recovery-policy
23
+ contract. It reuses only the provider-neutral failure/capacity/usage vocabulary
24
+ from `keble-helpers`; it does not import Data Infra wire types or provider
25
+ exceptions. Platform must convert each outer failure once into an immutable
26
+ `JobFailureSnapshot` and may not restore the removed `error_code` or
27
+ `retry_classification` fields.
28
+
29
+ ## Architecture
30
+
31
+ ```text
32
+ raw provider HTTP responses
33
+ -> platform-owned adapters
34
+ -> keble-idea schemas and services
35
+ -> platform-owned persistence/projection adapters
36
+ ```
37
+
38
+ MongoDB is canonical in the host application. Qdrant stores canonical concept
39
+ vectors only, Neo4j stores the concept graph only, Redis stores TTL search
40
+ frontiers, and RabbitMQ delivers identifiers for Mongo-backed queue envelopes.
41
+ Ideas are retrieved through scalar idea-to-concept postings rather than idea
42
+ vectors or multikey story-array scans.
43
+
44
+ Cost-bearing extraction and relationship protocols receive an
45
+ `EnvelopeExecutionIdentity` copied from the atomically leased Mongo envelope.
46
+ The envelope key identifies logical work; `attempt_number` identifies the
47
+ physical broker/worker retry. Optional `queued_at` and `leased_at` preserve the
48
+ exact durable queue interval without introducing provider or pricing ownership.
49
+ Financial adapters include the identity in provider attempt keys so redelivery
50
+ cannot overwrite or hide a second possible spend.
51
+
52
+ ## Development
53
+
54
+ Python 3.13 and `uv` are required.
55
+
56
+ ```bash
57
+ uv sync
58
+ uv run pytest -q -m "not live and not slow and not eval and not local_stack and not db_stack and not container"
59
+ npx --yes pyright .
60
+ uv build
61
+ ```
62
+
63
+ The portable test lane uses only reusable in-memory adapters from
64
+ `keble_idea.testing`. Stateful integration adapters belong to the platform and
65
+ must isolate and clean MongoDB, Redis, Qdrant, Neo4j, RabbitMQ, and artifact
66
+ state after each test.
67
+
68
+ ## Contract rules
69
+
70
+ - Persist only HIGH and MEDIUM ideas. LOW candidate details are discarded.
71
+ - Write exactly one minimal receipt for every content/generation terminal state.
72
+ - Keep receipts provider-neutral: physical token/image/duration usage remains in
73
+ `ProcessingUsage`, while monetary pricing and per-content allocation belong
74
+ exclusively to the platform-owned financial ledger. Receipt schema version 2
75
+ rejects the removed `cost_micros` field.
76
+ - Use the eight finite semantic facets; provider/source metadata is not a concept.
77
+ - Use `standalone_concept_error` at model boundaries so invalid facet labels
78
+ receive a typed correction before publication applies the same strict policy.
79
+ - Merge only HIGH-confidence PURPOSE concepts automatically and keep it reversible.
80
+ - Vectorize concepts only unless a separately approved retrieval eval changes the design.
81
+ - Use immutable generations and active pointers; never mutate active indexes in place.
82
+ - Persist named, collection-owned integer-version migration checkpoints so outer
83
+ workers resume by stable record key and never migrate a corpus at startup.
84
+ - Preserve original ASR and OCR independently from English-normalized fields;
85
+ unknown-language OCR belongs in `ocr_text_original`, never guessed into
86
+ `ocr_text_en` from the transcript language.
87
+ - Cutover only verified generations through compare-and-swap pointers and preserve
88
+ the immediately previous verified generation for exact rollback.
89
+ - Stamp relationship coverage with the exact embedding, neighborhood, and
90
+ relationship generations plus bounded neighbor similarities; a valid
91
+ null/no-relation result still completes coverage. Persisted current/previous
92
+ neighbor sets let outer adapters apply entry/exit hysteresis without all-pairs
93
+ comparison.
94
+ - Keep `relationship_priority_score` and `relationship_priority_at` as bounded,
95
+ provider-neutral scheduling hints. The platform derives them idempotently from
96
+ posting quality/time so Stage-B graph budget reaches high-value/recent concepts
97
+ first; they never change semantic concept identity or Stage-A search readiness.
98
+ - Compact alias postings asynchronously in bounded resumable pages; merge and
99
+ unmerge correctness must never depend on compaction finishing first. Derived
100
+ rows retain `origin_concept_key`, so unmerge removes them without deleting the
101
+ original posting identities.
102
+ - Search is bounded, concept-first, count-free, and cursor-session based.
103
+ - Cursor signatures bind expiry, frontier revision, and the complete generation/profile identity.
104
+ - Operator lifecycle is canonical and typed (schema version 2): content moves
105
+ `ACTIVE -> ARCHIVED -> ACTIVE` and enters `PURGING` terminally; ideas move
106
+ `ACTIVE -> RETIRED -> ACTIVE` and enter `PURGING` terminally. `archived_at` /
107
+ `retired_at` must match the state, transitions go through
108
+ `assert_lifecycle_transition`, and public reads exclude non-ACTIVE rows.
109
+ - Operator job commands use the canonical status sets: retry targets
110
+ `TERMINAL_JOB_STATUSES`, cancel targets `CANCELLABLE_JOB_STATUSES`
111
+ (never LEASED work), and purge work routes through `IdeaJobType.PURGE`.
112
+
113
+ ## Durable provider recovery
114
+
115
+ Each queue envelope snapshots the complete active
116
+ `ProviderRecoveryProfileSnapshot`, its matching `attempt_limit`, and an absolute
117
+ deadline. Automatic retry retains that snapshot. A manual retry also preserves
118
+ it unless the operator explicitly requests the active profile. Profile records
119
+ are append-only and activation uses a revision-guarded pointer; changing the
120
+ pointer affects future admissions only.
121
+
122
+ The initial profile is fixed at eight attempts, a 72-hour deadline, 30-second
123
+ fallback doubled to a one-hour cap, a 24-hour maximum provider hint,
124
+ deterministic 0-10% jitter, five unavailable failures in 60 seconds, a five-
125
+ minute open circuit, one half-open probe, and blocked release batches of 100.
126
+ Those are defaults for the first persisted profile, not module constants that
127
+ silently mutate existing jobs.
128
+
129
+ `retry_at_for_failure` anchors delay and jitter to the failure's immutable
130
+ observation time. Re-evaluating the same envelope attempt therefore returns the
131
+ same not-before timestamp. A provider hint above the submitted 24-hour policy
132
+ becomes `BLOCKED`; attempt/deadline exhaustion or permanent failure becomes
133
+ `DEAD_LETTERED`; operator action becomes `BLOCKED`. Only a retryable failure
134
+ within both budgets becomes `RETRY_SCHEDULED`.
135
+
136
+ `UpstreamFailureEvidence` retains bounded status/code/request identity, opaque
137
+ quota scope, exact capacity, physical-attempt count, usage, and a completeness
138
+ bit. Missing or `USAGE_ONLY` evidence on a physical call is billing unknown.
139
+ Payment requires a reviewed billing-code/account-status source; HTTP 402,
140
+ negative capacity, quota, and rate limiting are never sufficient by themselves.
141
+
142
+ Side effects if changes:
143
+
144
+ - Platform Mongo queue/profile/incident adapters and central indexes implement
145
+ these exact field paths and compare-and-swap semantics;
146
+ - Data Platform job and commerce-operation APIs expose the same failure/policy
147
+ facts through generated clients and translated frontend labels;
148
+ - finance records failed physical usage exactly once while pre-provider gate
149
+ rejection remains zero spend;
150
+ - `EnvelopeProcessResult` must continue to contain exactly one result reference
151
+ or failure snapshot.
152
+
153
+ ## Images are a critical asset
154
+
155
+ Content payloads treat visuals as first-class evidence:
156
+ `ProductContentPayload.image_artifacts` carries model-ready product photos,
157
+ `CommerceProfileContentPayload.image_artifacts` carries acquired creator or
158
+ seller portraits, `ShortVideoContentPayload.thumbnail_artifacts` carries safe
159
+ ranked-video thumbnails without transient playback URLs, and
160
+ `VideoContentPayload` preserves uploaded video bytes plus key frames.
161
+ `IdeaSearchMedia.from_payload` projects the representative image/video (with
162
+ `IdeaSearchSourceSummary` for type-specific display facts) onto every search
163
+ item so consuming platforms can render media-rich cards. Artifact references
164
+ stay checksum-addressed (`ArtifactRef`) — delivery URLs are always resolved by
165
+ the serving platform at read time.
166
+
167
+ ## Commerce discovery content
168
+
169
+ Trending commerce ingestion stays provider-neutral after the platform boundary:
170
+
171
+ ```python
172
+ profile = CommerceProfileContentPayload(
173
+ profile_type=CommerceProfileType.CREATOR,
174
+ display_name="Rocket Lab Notes",
175
+ image_artifacts=[acquired_profile_image],
176
+ )
177
+
178
+ video = ShortVideoContentPayload(
179
+ title="A compact model-rocket launch guide",
180
+ thumbnail_artifacts=[acquired_thumbnail],
181
+ )
182
+ ```
183
+
184
+ Products keep `ProductContentPayload`; creators and sellers share the typed
185
+ profile payload with a stable `profile_type`; channel-wide ranked videos use a
186
+ separate short-video payload. Provider names, provider response bags, volatile
187
+ playback URLs, and raw enum labels do not enter these durable contracts.