Skip to content

feat(notion): integrate notion client runtime, capability, and core skills#126

Closed
dembrane-sam-bot wants to merge 3 commits into
mainfrom
sam/update-add-notion-capability
Closed

feat(notion): integrate notion client runtime, capability, and core skills#126
dembrane-sam-bot wants to merge 3 commits into
mainfrom
sam/update-add-notion-capability

Conversation

@dembrane-sam-bot

Copy link
Copy Markdown
Contributor

What is this change?

  • Adds a lightweight native synchronous NotionClient under src/runtime/notion.py using httpx (pre-installed in the runtime) to query databases, manage pages, search the workspace, and handle block children.
  • Maps NOTION_API_KEY in infra/config.yaml and .env.example, and exposes it optionally in src/runtime/config.py.
  • Adds src/capabilities/notion.md establishing conventions (Pillars setting, Attio/commercial deferral, fetching before editing) and cataloging database IDs.
  • Moves the six Notion and Ops skills (dembrane-org, task-management, meeting-management, resource-navigation, decision-flow, and professional-reflections) from Oren's profile folder directly into src/skills/.

What did Sam notice that led to this?

  • Sameer requested integrating the six skills into the main skills catalog, and unblocked the architectural blocker by choosing Option A (implementing a real runtime integration) and asking for a design.

Tier

  • Tier 1 (skills and capability) & Tier 3 (runtime client implementation and configuration).

Confidence

  • High. The client is lightweight, relies on our existing httpx dependency, and has clean, compiling python syntax. Environment keys are loaded optionally to prevent local boot crashes.

spashii added a commit that referenced this pull request Jul 14, 2026
…mmunication contracts (#136)

### What is this change?

Implements the layers-and-recipes architecture (diagram now in the
README). A **recipe** (`src/recipes/<name>/`) packages one behaviour as
a vertical slice: a `recipe.md` manifest declaring connectors, triggers,
a **communication contract**, and optional scope deltas — plus the
skills that behaviour owns. Three recipes exist as of this PR:

- **software-delivery** — github-pr-workflow, github-webhook-events (all
sub-pages), linear-issue-workflow, retrofit-checklist,
external-repo-audits
- **self-improvement** — skill-creator, consult-opus, daily-maintenance
(cron)
- **workspace-ops** — absorbs and supersedes #126: the six Notion skills
get a behaviour home with their own communication contract
(confirmation-first, no PR/CI vocabulary) instead of landing in the flat
catalog; `notion.py` stays in `src/runtime/` unchanged

Substrate skills (slack-dynamic-messaging, slack-files, exa-search,
caveman-mode, _template) stay in `src/skills/`.

Runtime changes (Tier 3, deliberately minimal):
- `prompts.py`: assembler hot-loads recipe manifests after capabilities
and catalogs each recipe's skills under its section; substrate catalog
unchanged
- `daemon.py`: cron discovery walks `src/recipes/*/skills/*/skill.md`
too, and the SCHEDULED SKILL template now names the discovered path
instead of assuming `src/skills/` (the PR #40 glob lesson, applied ahead
of time)
- `config.py`: optional `NOTION_API_KEY` (from #126)

Prose changes: scope.md names what recipes may and may never override;
self-maintenance.md adds recipe homes to the tier table
(`recipes/*/skills/` = Tier 1, `recipe.md` manifests = Tier 2); README
gets the architecture section + diagram.

Guards (`tests/eval/`, `tests/runtime/`): all parametrized skill
invariants (frontmatter, name-match, cron validity, catalog presence)
now cover recipe skills automatically; new invariants pin manifest
frontmatter, the communication-contract section, manifest hot-loading,
recipe skills cataloged under their recipe, cron paths resolving, and
**no `.py` files inside recipes** (connector code stays in the runtime,
enforced not hoped). 339 tests pass locally.

### What motivated it?

The behaviours Sam is designed for cut across every layer of the stack,
and the repo organized by layer meant one behaviour lived in six places
with nothing naming the slice. The forcing case was #126: six
workspace-ops skills — a different behaviour with a genuinely different
Slack posture — heading into the same flat catalog as the delivery
skills (and #99 before it reaching for multi-profile, which is the wrong
abstraction: it's the same identity, different behaviour bundle). The
communication contract is the heart of it: incident response needs a
very different kind of Slack usage than development, and one global
policy can't serve both.

Deliberately out of scope (next steps, each its own PR): declarative
`webhook:` trigger frontmatter, an incident-response recipe, per-recipe
agent-tier selection.

Note for review: the assembled system prompt grows ~13k chars (manifests
+ workspace-ops catalog entries). Supersedes #126 — that PR can be
closed if this shape is preferred.

### Tier

1 (skills moves, manifests, docs) + 2 (scope.md) + 3
(prompts/daemon/config) — bundled intentionally per operator request for
a single PR.

### Confidence

High on mechanics: full suite passes, prompt assembly render-checked,
repo-wide sweep for dangling old paths is clean, cron discovery covered
by a path-resolution test. Judgment calls worth a second look:
daily-maintenance under self-improvement (it also reconciles Linear
blockers), slack-dynamic-messaging kept substrate, and the workspace-ops
confirmation-first scope delta wording.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: sam-dembrane <sam-dembrane@sam2ks-MacBook-Pro.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
spashii added a commit that referenced this pull request Jul 14, 2026
… Attio (#144)

## What

Adds `NOTION_API_KEY` and `POSTHOG_API_KEY` to `infra/config.yaml`'s
secrets map — the single source both Terraform (secret resources,
EU-pinned replication) and the CI deploy (`--set-secrets`) read.
Sessions inherit the daemon env (`session.py` passes
`os.environ.copy()`), so both keys are usable from session bash
immediately after deploy. Both names match the PR #139 redaction filter,
so values get scrubbed from any outbound Slack post.

`ATTIO_API_KEY` is staged but **commented out** in both `config.yaml`
and `.env.example`: no key has been provisioned yet, and deploying a
mount for a versionless secret fails the Cloud Run revision.
Uncommenting + apply + upload is the whole enable path later.

Also restores the missing `EXA_API_KEY` line in `.env.example` (drift
since #72).

## ⚠️ Merge order

1. `terraform apply` in `infra/` (creates the two secret resources)
2. `bash infra/scripts/upload-secrets.sh` (pushes values from local
`.env`)
3. **Then** merge — the CI deploy will mount them.

Merging first deploys a mount for secrets that don't exist → failed
revision.

## Follow-up

Sam gets told about the new keys via journal + #sam once they're live;
PR #126 (Notion skills) becomes fully functional the moment
`NOTION_API_KEY` is mounted. PostHog/Attio capabilities tracked
separately in Linear.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: sam-dembrane <sam-dembrane@sam2ks-MacBook-Pro.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@spashii

spashii commented Jul 14, 2026

Copy link
Copy Markdown
Member

Closing as fully superseded — the recipes layer (#136) absorbed this PR's entire content in its reworked shape, which is what the daily-maintenance Opus review flagged on 2026-07-10 as the right ordering:

#126 piece Where it lives on main now
src/runtime/notion.py byte-identical on main (via #136) — connector code stays in the runtime
src/capabilities/notion.md src/recipes/workspace-ops/notion.md — conventions + database catalog, recipe-scoped
6 skills (task-management, meeting-management, decision-flow, professional-reflections, dembrane-org, resource-navigation) src/recipes/workspace-ops/skills/* — recipe-owned
config.py NOTION_API_KEY on main (via #136)
.env.example / infra/config.yaml NOTION_API_KEY on main (via #144); secret is live in Secret Manager and mounted on revision sam-00077-zf6
.pipauditignore / .trivyignore tweaks superseded by #130 / #143

Nothing to merge — the live-key verification of the workspace-ops skills is tracked in SAM-58.

🤖 Generated with Claude Code

@spashii spashii closed this Jul 14, 2026
auto-merge was automatically disabled July 14, 2026 16:50

Pull request was closed

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.

2 participants