overengineeringstudio / overengineeringstudio/effect-utils

notion-md: first-class generated/provenance marker for synced pages

Open
#751 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area:notion origin:agent type:feature
Dominant language
TypeScript
Stars
82
Forks
2
Avg merge
1d 8h
Merged PRs (30d)
121

Description

Problem

When a machine-generated artifact is synced to Notion via @overeng/notion-md, there is currently no clean, Notion-native way to mark the resulting page as generated (or carry any provenance). The only honest options today are:

  • An HTML comment / callout block in the body — visible clutter, not filterable, and notion-md has no typed handle to keep it canonical (a human edit or re-pull can move/duplicate it).
  • A real DB property (generated checkbox/select) — fully queryable, but only works when the page is a data_source/database row.

The blocker is upstream and parent-type-specific: for a page-parented page, the Notion API only allows updating the title property; arbitrary properties (select/checkbox/rich_text/…) require a data_source parent. See https://developers.notion.com/reference/patch-page ("properties … can only be used if the page's parent is a data source, aside from updating the title").

So a generated/provenance marker that should work across a page-parented hierarchy (e.g. a generated docs tree) has no first-class home in the current NmdFrontmatterV2 envelope.

Relevant current surfaces

  • Envelope: NmdFrontmatterV2packages/@overeng/notion-effect-client/src/nmd.ts (notion_md = { …, parent, page, properties }).
  • Two write paths in packages/@overeng/notion-md/src/live.ts:
    • updatePagePropertiesNotionPages.update({ properties }) (rejected for non-title props on page-parented pages).
    • updatePageMetadataNotionPages.update({ title?/icon?/cover?/… })title/icon/cover are valid on any parent.
  • The only parent-agnostic, round-tripped non-property page metadata is icon / cover (NmdPageState, nmd.ts). There is no page-level description/arbitrary-metadata field for standalone pages.

Proposed general mechanism

Add one optional, schema-validated provenance field to the notion_md envelope, and let notion-md choose the Notion surface per parent type at push time. It is general (a small structured record, not a boolean), and the projection is the package's responsibility, not the caller's:

notion_md:
  # …
  provenance:                 # optional; absent ⇒ no marker (back-compat)
    generated: true
    generator: "<source that produced this page>"
    source_hash: "sha256:…"   # free, schema-validated k/v

Projection (owned by notion-md, derived from parent):

  • data_source / database parent → write a real DB property (configurable generated checkbox/select + optional rich_text for generator/source). Fully filterable; reuses the existing property encoder + write path.
  • page / block / workspace parent → set the page icon to a stable provenance icon (parent-agnostic, round-tripped via updatePageMetadata) and keep the record in frontmatter as source of truth. Optionally a single notion-md-managed marker block kept canonical (not an unmanaged body block). Searchable, not filterable — the genuine upstream ceiling for standalone pages.

This degrades honestly: standalone pages get search/visual provenance, DB rows get native filtering, and the caller never has to know the difference. Because notion-md owns both the write and the read-back of whichever surface it picked, it round-trips cleanly.

Use cases beyond the originating one

  • Generated docs tree (the originating case): a page-parented hierarchy regenerated wholesale from a catalog; each page should self-declare it's generated + which generator/source-hash produced it.
  • Synced records in a tracker DB: rows imported/maintained by automation that humans should be able to filter by "machine-managed vs hand-edited" — needs the native DB-property projection.
  • Report/digest pages posted by a bot under a parent page: want a visible/searchable "auto-generated, do not hand-edit" provenance without a body banner.

Constraint reference

The page-parented property limitation is exactly the class of inherent Notion-API edge catalogued in #602 — cross-linking for context. This issue is a notion-md feature (envelope field + parent-aware projection), not a datasource-sync child workstream (#698).

Filed from downstream investigation against effect-utils@main.

Posted on behalf of @schickling
field value
agent_name 💪 cl2-grit
agent_session_id 20af0604-b67f-4c87-a5f5-631198740bab
agent_tool Claude Code
agent_tool_version 2.1.160
agent_runtime Claude Code 2.1.160
agent_model claude-opus-4-8
worktree dotfiles/schickling/2026-06-03-scg-v2
machine dev3
tooling_profile dotfiles@unknown-dirty

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with NmdFrontmatterV2 in packages/@overeng/notion-effect-client/src/nmd.ts, then trace updatePageProperties and updatePageMetadata in packages/@overeng/notion-md/src/live.ts. Compare the existing page metadata and property round trips against the parent-type constraints; done means the optional provenance record is validated and consistently written and read back for the supported parent types.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.