Skip to content

docs: rewrite v2 cookbooks for the unified context API, restore Cookbooks tab (PRO-1618) - #302

Open
SohamRatnaparkhi wants to merge 7 commits into
soham/pro-1618-openapi-contextfrom
soham/pro-1618-cookbooks-unified
Open

SohamRatnaparkhi wants to merge 7 commits into
soham/pro-1618-openapi-contextfrom
soham/pro-1618-cookbooks-unified

Conversation

@SohamRatnaparkhi

Copy link
Copy Markdown
Contributor

Summary

Stacked on #301 (soham/pro-1618-openapi-context), the top of the PRO-1618 docs stack (#296#298#299#301).

The 12 cookbooks in cookbooks/v2/ were written against the deprecated split knowledge/memory schema (type, app_knowledge, memories, documents, chunk_content, old graph_context response fields) and were hidden: removed from docs.json, noindex: true, deprecation <Warning>. This PR rewrites them for the unified API and brings the tab back.

  • Ingest — every example uses POST /context/ingest with context items (text/conversation, context_id, title, happened_at, attributes, enrich, upsert). Recipes that uploaded PDFs/files now extract text client-side (pypdf, named plainly) since there is no file upload on a unified database.
  • Split schema → collections — shared documents in named collections, per-user context in user-<id> collections, replacing the knowledge/memory split.
  • QueryPOST /query with current fields (attributes filters, mode, alpha, recency_bias, follow_forceful_relations) and reads data.chunks / data.graph / data.llm_prompt.
  • Navigation — Cookbooks tab restored in docs.json between Guides and API Reference (its main position), pointing at the v2 pages in the same group/order as origin/main; noindex and deprecation warnings removed; index.mdx cards updated.
  • SDK snippets follow api-reference/v2/sdks.mdx call shapes with a note that they need an SDK release generated from the current spec.

Test plan

  • mint broken-links — clean
  • npm run hygiene (mintlify-hygiene check) — clean
  • Every ```json fence in the 13 touched files parses
  • No app_knowledge / memories / documents / metadata_filters / chunk_content / type: knowledge|memory / noindex remain outside historical changelog text

Generated with Devin

…ooks tab (PRO-1618)

The 12 cookbooks in cookbooks/v2 were written against the deprecated
split knowledge/memory schema (type, app_knowledge, memories, documents,
chunk_content, graph_context response fields) and hidden from navigation.

- All ingestion examples now use POST /context/ingest with context items
  (text, context_id, title, happened_at, attributes, enrich, upsert).
- File-upload recipes extract text client-side (pypdf, named plainly)
  since there is no file upload on a unified database.
- All queries use POST /query with current request fields (attributes
  filters, mode, alpha, recency_bias) and read data.chunks/.graph/
  .llm_prompt instead of chunk_content/graph_context.
- The old knowledge/memory split maps to collections: shared documents
  in named collections, per-user context in user-<id> collections.
- Cookbooks tab restored in docs.json pointing at the v2 pages in the
  same group/order as main; noindex and deprecation warnings removed.
- Every JSON block parses; mint broken-links and mintlify-hygiene pass.

Signed-off-by: SohamRatnaparkhi <soham@hydradb.com>
@greptile-apps

greptile-apps Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

The PR should not merge until the published feedback request schema again represents the server-required conditional fields and database/collection dependency.

Summary

Rewrites the v2 cookbooks around unified context ingestion and retrieval, restores their navigation, and updates the generated API-reference view and SDK guidance.

  • Replaces the deprecated knowledge/memory split with context items and collection-based organization.
  • Updates ingestion, query, readiness polling, response handling, ACL, and client examples.
  • Restores the Cookbooks tab and removes deprecation/no-index treatment.
  • Refreshes the v2 OpenAPI documentation view and associated endpoint guidance.
  • Greptile automatically discovered a related ticket that helped explain the purpose of this PR: remove the public knowledge/memory fork while preserving compatibility for existing split-layout tenants.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  App[Application] -->|POST /context/ingest| DB[(Unified database)]
  DB --> Shared[Shared collections]
  DB --> User[Per-user collections]
  App -->|POST /query| Query[Unified retrieval]
  Shared --> Query
  User --> Query
  Query --> Results[Chunks, graph, relations, llm_prompt]
Loading

Reviews (7) · Last reviewed commit: "Merge #301 (docs view of the spec) into ..."

Comment thread cookbooks/v2/internal-search-perplexity.mdx Outdated
Comment thread cookbooks/v2/internal-search-perplexity.mdx
Comment thread cookbooks/v2/ai-linkedin-recruiter.mdx
Comment thread cookbooks/v2/ai-linkedin-recruiter.mdx
Comment thread cookbooks/v2/cookbook-10-ai-financial-analyst.mdx Outdated
@greptile-apps

This comment has been minimized.

@openhack-agent

openhack-agent Bot commented Sep 23, 2026

Copy link
Copy Markdown

OpenHack Summary

Security review of docs: rewrite v2 cookbooks for the unified context API, restore Cookbooks tab (PRO-1618). 14 changed files; 2 findings at or above the low reporting threshold.

P1: Critical 0   P2: High 2   P3: Medium 0   P4: Low 0

Confidence Score: 2/5

Review the findings below before merging.

Security merge-readiness rubric: 1 = critical, 2 = high, 3 = medium, 4 = low, 5 = no reportable findings. This score reflects scan findings, not a guarantee of correctness or complete coverage.

Files Needing Attention: cookbooks/v2/glean-clone.mdx

Important Files Changed
  • cookbooks/v2/ai-chief-of-staff.mdx (modified)
  • cookbooks/v2/ai-linkedin-recruiter.mdx (modified)
  • cookbooks/v2/ai-onboarding-agent.mdx (modified)
  • cookbooks/v2/ai-travel-planner.mdx (modified)
  • cookbooks/v2/competitive-intelligence-agent.mdx (modified)
  • cookbooks/v2/cookbook-01-build-cursor-for-docs.mdx (modified)
  • cookbooks/v2/cookbook-04-build-notion-ai.mdx (modified)
  • cookbooks/v2/cookbook-10-ai-financial-analyst.mdx (modified)
  • cookbooks/v2/customer-support-agent.mdx (modified)
  • cookbooks/v2/glean-clone.mdx (modified)
  • cookbooks/v2/hydradb-cookbook-06.mdx (modified)
  • cookbooks/v2/index.mdx (modified)
  • cookbooks/v2/internal-search-perplexity.mdx (modified)
  • docs.json (modified)

AI Autofix in OpenHack Fix all in Codex Fix all in Claude Fix all in Cursor Fix all in Conductor

Prompt To Fix With AI
Review the findings for https://github.com/hydra-db/mintlify-docs/pull/302 at commit 83bf9207f931f7b836c52433999c1a4cf3d51b6b. Verify each finding against the current code before fixing it. Preserve unrelated changes and run focused regression tests.

### Issue 1: [P2] Retention job deletes shared knowledge items instead of only user context
Vulnerability type: CWE-459: Incomplete Cleanup / Improper Data Retention Scope
cookbooks/v2/glean-clone.mdx:1323

This PR changes the documented DataPrivacyManager retention flow from a memory-scoped operation to an unscoped context operation. Before the change, listing used type: 'memory' and read data.user_memories, and deletion also included type: 'memory'. After the change, findExpiredItems posts only database and include_fields, reads data.sources, and deleteOldData posts only database and ids. applyRetentionPolicy does not pass collection, and dataTypes is not used. In the same cookbook, shared workplace content is ingested into the database, so the scheduled job can select and delete old shared knowledge items rather than only per-user context. The timestamp/happened_at mismatch is a separate correctness concern within the same retention root cause: it may cause items to be missed if timestamp is absent, but does not provide a safe scope.

Recommendation: Restore an explicit retention scope and enforce it end to end. Define the eligible per-user collections or a declared attribute/type for retention, honor policy.dataTypes, and pass the selected collection or filter to both listing and deletion. Use the actual ingest-time temporal field consistently, including happened_at if that is the API's field. Before deletion, perform a dry run, audit the candidate IDs and collections, enforce a maximum deletion count, and abort on missing or unexpected scope. Add tests proving shared knowledge items are never selected by a user-context retention policy and that deletion requests retain the same scope.

---

### Issue 2: [P2] Personalized search removes per-user collection isolation while relying on unstamped ACLs
Vulnerability type: CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
cookbooks/v2/glean-clone.mdx:612

The PR changes the personalized search example from a query scoped to the caller's collection to an unscoped query using `acl: [userEmail]`. The new comment claims that this ACL restricts results, but the cookbook's normalized item and connector examples do not set `acl` on ingested records. Under the documented ACL semantics, unstamped records are unrestricted, so the query can retrieve other users' context collections and other unstamped content. Before the change, `collection: userId` prevented the caller from reaching another user's collection; after the change, that isolation boundary is removed.

Recommendation: Restore an explicit retrieval boundary. Prefer querying only the intended shared collections plus the caller's own collection, for example `collections: ["slack", "docs", "email", "github", `user-${userId}`]`, after validating that the shared collections are appropriate. Alternatively, if ACL filtering is required, stamp every ingested item—including normalized connector records, webhook records, and user profiles—with the correct `acl` allow-list and verify ACL behavior with cross-user tests. Do not describe query-time `acl` alone as isolation for unstamped records.

Last reviewed commit: 83bf920 · View review on OpenHack


TIP: Mention @openhack-agent in a PR comment to request a review or ask a question. Use @openhack-agent fix all for every finding, or @openhack-agent fix unresolved threads for open review threads only.

@openhack-agent openhack-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenHack reviewed this commit. See the OpenHack Summary for the confidence score and fix actions.

…litter

- Poll databases.status until ready_for_ingestion after every
  databases.create (creation is asynchronous).
- Add API-Version: 2 to the raw fetch headers in
  internal-search-perplexity and read ingest IDs from data.results.
- glean-clone personalized search no longer scopes collection=user_id:
  it fans out across shared and user collections and passes the
  caller's email as the acl principal so stored ACLs are enforced.
- ai-linkedin-recruiter: write reranked candidates back to data.chunks
  so downstream consumers see the fit-score ordering.
- cookbook-10: hard-cut oversized paragraphs at a UTF-8-safe byte
  boundary so no context item can exceed the 1 MiB text limit.

Signed-off-by: SohamRatnaparkhi <soham@hydradb.com>

@openhack-agent openhack-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenHack reviewed this commit. See the OpenHack Summary for the confidence score and fix actions.

// Search with personalized query enrichment derived from the user's local profile.
// No collection scope: the query fans out across shared source collections and the
// user's own collection. acl restricts results to what the caller may retrieve.
const searchWithUserContext = async (query: string, database: string, userId: string, userEmail: string) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: High Personalized search removes per-user collection isolation while relying on unstamped ACLs

Vulnerability type: CWE-200: Exposure of Sensitive Information to an Unauthorized Actor

The PR changes the personalized search example from a query scoped to the caller's collection to an unscoped query using acl: [userEmail]. The new comment claims that this ACL restricts results, but the cookbook's normalized item and connector examples do not set acl on ingested records. Under the documented ACL semantics, unstamped records are unrestricted, so the query can retrieve other users' context collections and other unstamped content. Before the change, collection: userId prevented the caller from reaching another user's collection; after the change, that isolation boundary is removed.

Location: cookbooks/v2/glean-clone.mdx:612

Recommendation:

Restore an explicit retrieval boundary. Prefer querying only the intended shared collections plus the caller's own collection, for example collections: ["slack", "docs", "email", "github", user-${userId}], after validating that the shared collections are appropriate. Alternatively, if ACL filtering is required, stamp every ingested item—including normalized connector records, webhook records, and user profiles—with the correct acl allow-list and verify ACL behavior with cross-user tests. Do not describe query-time acl alone as isolation for unstamped records.

Prompt To Fix With AI
Review the findings for https://github.com/hydra-db/mintlify-docs/pull/302 at commit 7ab33a3d2019f64cd89aad60f50d9891fcd1d363. Verify each finding against the current code before fixing it. Preserve unrelated changes and run focused regression tests.

### Issue 1: [P2] Personalized search removes per-user collection isolation while relying on unstamped ACLs
Vulnerability type: CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
cookbooks/v2/glean-clone.mdx:612

The PR changes the personalized search example from a query scoped to the caller's collection to an unscoped query using `acl: [userEmail]`. The new comment claims that this ACL restricts results, but the cookbook's normalized item and connector examples do not set `acl` on ingested records. Under the documented ACL semantics, unstamped records are unrestricted, so the query can retrieve other users' context collections and other unstamped content. Before the change, `collection: userId` prevented the caller from reaching another user's collection; after the change, that isolation boundary is removed.

Recommendation: Restore an explicit retrieval boundary. Prefer querying only the intended shared collections plus the caller's own collection, for example `collections: ["slack", "docs", "email", "github", `user-${userId}`]`, after validating that the shared collections are appropriate. Alternatively, if ACL filtering is required, stamp every ingested item—including normalized connector records, webhook records, and user profiles—with the correct `acl` allow-list and verify ACL behavior with cross-user tests. Do not describe query-time `acl` alone as isolation for unstamped records.

AI Autofix in OpenHack Fix in Codex Fix in Claude Fix in Cursor Fix in Conductor


TIP: Reply @openhack-agent or @openhack-agent fix this to fix this finding. To ask a question, mention @openhack-agent followed by your question.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

83bf920: Verification is inconclusive. This finding remains open and will be checked again on the next scan.

Comment thread cookbooks/v2/ai-linkedin-recruiter.mdx
Comment thread cookbooks/v2/cookbook-10-ai-financial-analyst.mdx Outdated
- ai-linkedin-recruiter: recruiter signals are now stamped with
  acl: ["user_email:<email>"] and every recruiter-scoped query passes
  the caller's email as the acl principal. The recruiter identity is a
  session-derived object, never caller input, so one recruiter cannot
  read another's search history or preferences.
- glean-clone: document that per-user context items must carry an acl
  (unstamped items are unrestricted) and add a stamped record_user_signal
  ingest example alongside the acl-aware search.
- cookbook-10: the PDF splitter's hard-cut now backs off to a real
  UTF-8 character boundary instead of decoding with errors="ignore",
  so no bytes are silently dropped mid-character.

Signed-off-by: SohamRatnaparkhi <soham@hydradb.com>

@openhack-agent openhack-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenHack reviewed this commit. See the OpenHack Summary for the confidence score and fix actions.

async findExpiredMemories(database, cutoff, collection = null) {
const body = { type: 'memory', database: database };
async findExpiredItems(database, cutoff, collection = null) {
const body = { database: database, include_fields: ['timestamp'] };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: High Retention job deletes shared knowledge items instead of only user context

Vulnerability type: CWE-459: Incomplete Cleanup / Improper Data Retention Scope

This PR changes the documented DataPrivacyManager retention flow from a memory-scoped operation to an unscoped context operation. Before the change, listing used type: 'memory' and read data.user_memories, and deletion also included type: 'memory'. After the change, findExpiredItems posts only database and include_fields, reads data.sources, and deleteOldData posts only database and ids. applyRetentionPolicy does not pass collection, and dataTypes is not used. In the same cookbook, shared workplace content is ingested into the database, so the scheduled job can select and delete old shared knowledge items rather than only per-user context. The timestamp/happened_at mismatch is a separate correctness concern within the same retention root cause: it may cause items to be missed if timestamp is absent, but does not provide a safe scope.

Location: cookbooks/v2/glean-clone.mdx:1323

Recommendation:

Restore an explicit retention scope and enforce it end to end. Define the eligible per-user collections or a declared attribute/type for retention, honor policy.dataTypes, and pass the selected collection or filter to both listing and deletion. Use the actual ingest-time temporal field consistently, including happened_at if that is the API's field. Before deletion, perform a dry run, audit the candidate IDs and collections, enforce a maximum deletion count, and abort on missing or unexpected scope. Add tests proving shared knowledge items are never selected by a user-context retention policy and that deletion requests retain the same scope.

Prompt To Fix With AI
Review the findings for https://github.com/hydra-db/mintlify-docs/pull/302 at commit 83bf9207f931f7b836c52433999c1a4cf3d51b6b. Verify each finding against the current code before fixing it. Preserve unrelated changes and run focused regression tests.

### Issue 1: [P2] Retention job deletes shared knowledge items instead of only user context
Vulnerability type: CWE-459: Incomplete Cleanup / Improper Data Retention Scope
cookbooks/v2/glean-clone.mdx:1323

This PR changes the documented DataPrivacyManager retention flow from a memory-scoped operation to an unscoped context operation. Before the change, listing used type: 'memory' and read data.user_memories, and deletion also included type: 'memory'. After the change, findExpiredItems posts only database and include_fields, reads data.sources, and deleteOldData posts only database and ids. applyRetentionPolicy does not pass collection, and dataTypes is not used. In the same cookbook, shared workplace content is ingested into the database, so the scheduled job can select and delete old shared knowledge items rather than only per-user context. The timestamp/happened_at mismatch is a separate correctness concern within the same retention root cause: it may cause items to be missed if timestamp is absent, but does not provide a safe scope.

Recommendation: Restore an explicit retention scope and enforce it end to end. Define the eligible per-user collections or a declared attribute/type for retention, honor policy.dataTypes, and pass the selected collection or filter to both listing and deletion. Use the actual ingest-time temporal field consistently, including happened_at if that is the API's field. Before deletion, perform a dry run, audit the candidate IDs and collections, enforce a maximum deletion count, and abort on missing or unexpected scope. Add tests proving shared knowledge items are never selected by a user-context retention policy and that deletion requests retain the same scope.

AI Autofix in OpenHack Fix in Codex Fix in Claude Fix in Cursor Fix in Conductor


TIP: Reply @openhack-agent or @openhack-agent fix this to fix this finding. To ask a question, mention @openhack-agent followed by your question.

@SohamRatnaparkhi
SohamRatnaparkhi added this pull request to stack #300 September 23, 2026 16:40
@github-actions

Copy link
Copy Markdown

✅ Mintlify Hygiene

No issues found.

SohamRatnaparkhi and others added 4 commits September 23, 2026 23:28
…kbooks-unified

Conflicts in get-started/v2/introduction.mdx and get-started/v2/core-concepts.mdx
resolved to the wording that does not call context "items".

Signed-off-by: SohamRatnaparkhi <soham@hydradb.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: SohamRatnaparkhi <soham@hydradb.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: SohamRatnaparkhi <soham@hydradb.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SohamRatnaparkhi

Copy link
Copy Markdown
Contributor Author

@greptile-apps On "Feedback constraints were dropped": this is deliberate. api-reference/v2/openapi.json is now the docs view that hydradb-application builds for the reference site (docs/openapi.docs.json, app PR #1669). The SDKs are not generated from it; they use the app's docs/openapi.json, which still carries every rule on feedback.SubmitRequest (the feedback/ground_truth anyOf and the dependentSchemas). Mintlify draws validation-only unions as untitled "Option 1 / Option 2" tabs with nothing in them, so the docs view drops them and states the rule on the body instead: "Send feedback, ground_truth, or both. A request with neither is rejected with 400." The server enforces the rules either way.

@greptile-apps

greptile-apps Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

That distinction addresses the concern. If api-reference/v2/openapi.json is intentionally a Mintlify-only view, while SDK generation continues to use docs/openapi.json with the complete feedback.SubmitRequest anyOf/dependentSchemas, then dropping the validation-only unions from the rendered docs is acceptable. The explicit body note preserves the user-facing requirement, and the server remains the source of enforcement. I’m withdrawing the finding about the feedback constraints.

This branch has not been deployed

No deployments
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.

1 participant