-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Problem
External Convex component packages (@convex-dev/workpool, @convex-dev/workflow, etc.) are foundational primitives for the platform architecture. AI coding sessions need deep context about how and when to use them — not just API signatures. Today this context exists in three disconnected places:
| Source | What It Provides | Maintenance |
|---|---|---|
.d.ts type declarations |
API signatures, basic JSDoc | Ships with npm — automatic |
Git subtrees (deps-packages/) |
Full source code | Manual git subtree pull |
Claude Code skills (~/.claude/skills/) |
~105 KB curated production patterns | Manual — separate from source |
The gap: No structured, source-of-truth mechanism documents our usage patterns for these dependencies. The skills bridge the gap but are manually maintained and disconnected from the codebase's annotation system.
Analogy: This is the pre-TypeScript era for AI context. Before .d.ts files, JavaScript consumers maintained separate @types/ packages. We're doing the same thing with skills — maintaining separate context files for packages that should carry (or generate) their own AI context.
Proposal: Three-Layer Dependency Context
Layer 1: Decision Specs for Dependency Patterns (PDRs)
Use the existing decision spec format to document architectural decisions about dependency usage. These are permanent records of how and when to use each external primitive — the same way PDRs document internal architectural decisions.
Examples of dependency PDRs:
| PDR | Decision |
|---|---|
| PDR-NNN: Workpool Usage Patterns | When to use workpool vs workflow vs action-retrier. Partition key strategy. onComplete as mandatory pattern. Dead letter handling requirement. |
| PDR-NNN: Workflow Determinism Contract | What is/isn't allowed in workflow steps. Versioning strategy for workflow structure changes. Size limits and their implications. |
| PDR-NNN: Event Bus ↔ Workpool Integration | How EventBus delegates to workpool. Context shape for onComplete. Partition key derivation from event streams. |
| PDR-NNN: Agent ↔ Workpool Orchestration | How agent bounded contexts use workpool for durable tool execution. Priority separation pattern. |
Why PDRs fit:
- PDRs are permanent architectural records (like events — never deleted)
- They document why a pattern was chosen, not just what the API does
- They're already consumed by the delivery-process generators for ADR documentation
- They're Gherkin-structured with Rules, Invariants, and Rationale — perfect for capturing usage constraints
PDR structure for dependency patterns:
@libar-docs
@libar-docs-pattern:WorkpoolUsagePatterns
@libar-docs-adr-status:accepted
@libar-docs-category:dependency-pattern
Feature: Workpool Usage Patterns
**Context:** The platform uses @convex-dev/workpool as the primary
durable execution primitive for event processing, projections,
and agent tool execution.
**Decision:** Establish canonical patterns for workpool usage
across all platform packages.
Rule: Always use onComplete for production reliability
**Invariant:** Every workpool enqueue in production code must
have an onComplete handler that handles success, failure,
and cancellation.
**Rationale:** Without onComplete, failed work items are silently
lost. The dead letter pattern requires onComplete to capture
failures for reprocessing.
@acceptance-criteria @happy-path
Scenario: Dead letter recording on workpool failure
Given an event subscription using workpool
When the processing action fails after all retries
Then the onComplete handler records a dead letter
And the dead letter contains the original event context
Rule: Use partition keys for stream isolation
...
Rule: Prefer workpool over workflow for single-step durable work
...Layer 2: Consumer-Side Source Annotations
Extend the @libar-docs taxonomy with tags that annotate where and how external dependencies are used in the codebase:
New tags:
| Tag | Location | Purpose |
|---|---|---|
@libar-docs-uses-external |
TypeScript | Declares external package dependency |
@libar-docs-usage-pattern |
TypeScript | Names the canonical usage pattern (from PDR) |
@libar-docs-usage-context |
TypeScript | Brief description of usage in this specific location |
Example in source code:
// packages/platform-core/src/infrastructure/eventSubscriptions.ts
/**
* @libar-docs
* @libar-docs-pattern EventSubscriptionInfrastructure
* @libar-docs-uses-external @convex-dev/workpool
* @libar-docs-usage-pattern onComplete-dead-letter
* @libar-docs-usage-context Workpool processes events with partition-key
* isolation per stream. onComplete triggers dead-letter recording on failure.
*/// packages/platform-core/src/sagas/orderFulfillment.ts
/**
* @libar-docs
* @libar-docs-pattern SagaOrchestration
* @libar-docs-uses-external @convex-dev/workflow
* @libar-docs-usage-pattern saga-compensation
* @libar-docs-usage-context Workflow orchestrates multi-step order fulfillment
* with compensation logic for rollback on failure.
*/What this enables:
- Generators can produce a dependency usage map — which patterns use which packages, and how
- Process API can answer: "show me all patterns that use workpool" or "show me all onComplete-dead-letter usages"
- New team members (human or AI) can see the canonical patterns in context
Layer 3: Generated AI Context (Skills as Projections)
Apply the core delivery-process principle — docs are projections of annotated source — to AI context files:
Decision Specs (PDRs) → How/when to use each dependency
+ (architectural patterns)
Source Annotations → Where each dependency is used
(@libar-docs-uses-external) (concrete usage sites)
+
Upstream Package Docs → API reference
(AGENTS.md / .d.ts / README) (signatures, parameters)
↓
Generated Skills → Curated, contextualized AI context
(~/.claude/skills/) (projection — never manually edited)
Generator pipeline:
- Extract dependency PDRs (decision specs with
@libar-docs-category:dependency-pattern) - Extract usage annotations from TypeScript source (
@libar-docs-uses-external) - Merge with upstream package docs (AGENTS.md if available, README, .d.ts JSDoc)
- Transform into skill format: SKILL.md (overview) + REFERENCE.md (API) + EXAMPLES.md (patterns from PDRs + usage sites)
Result: Skills become generated artifacts — same as PATTERNS.md or ROADMAP.md. When a new usage pattern is added to source code, or a new PDR documents a dependency decision, the skill regenerates automatically.
Upstream Contribution (Optional, Ecosystem-Level)
Propose AGENTS.md files for upstream Convex component repos (get-convex/workpool, get-convex/workflow, etc.). This would provide the "base layer" of AI context that ships with npm install:
@convex-dev/workpool/
├── dist/ (compiled JS + .d.ts)
├── src/ (TypeScript source)
├── AGENTS.md (AI context — generic API patterns)
├── README.md (human docs)
└── package.json ("files": ["dist", "src", "AGENTS.md"])
AGENTS.md is emerging as the cross-tool standard (Linux Foundation stewardship, 20+ tool support including Claude Code). Even without this, the consumer-side layers (PDRs + annotations) provide full value independently.
Connection to Spec Graduation (#21)
This proposal complements #21 (Spec Graduation):
| Issue | What Graduates | Into What |
|---|---|---|
| #21 Spec Graduation | Completed tier 1 planning specs | Package executable specs + epic specs |
| This issue | External dependency knowledge | Decision specs + source annotations + generated skills |
Both follow the same principle: design-time artifacts get absorbed into the appropriate permanent home, and generated documentation is a projection of annotated source.
The dependency PDRs also provide a natural home for patterns that don't have executable specs (identified in #21 as needing decision specs rather than behavior tests).
Scope & Phasing
Phase 1: Dependency Decision Specs
- Define
@libar-docs-category:dependency-patternin taxonomy - Create PDR template for dependency usage patterns
- Write first dependency PDR: Workpool Usage Patterns (highest usage, most complex)
- Write second dependency PDR: Workflow Determinism Contract
- Validate PDRs are extracted correctly by existing generators
Phase 2: Consumer-Side Annotations
- Add
@libar-docs-uses-externaltag to taxonomy - Add
@libar-docs-usage-patterntag to taxonomy - Annotate existing high-usage dependency sites (eventSubscriptions, sagas, projections)
- Add Process API query:
pnpm process:query -- arch external-deps - Add Process API query:
pnpm process:query -- list --uses-external @convex-dev/workpool
Phase 3: Dependency Usage Map Generator
- New codec:
DependencyUsageCodecthat produces dependency map documentation - Output:
docs-living/DEPENDENCIES.mdwith per-package usage patterns and sites - Cross-reference with dependency PDRs for architectural context
Phase 4: Skill Generation Pipeline
- Design skill template format (SKILL.md / REFERENCE.md / EXAMPLES.md sections)
- Build generator that merges: dependency PDRs + usage annotations + upstream docs
- Output:
~/.claude/skills/{package-name}/as generated artifacts - Add
pnpm docs:skillscommand to regenerate skills from source
Phase 5: Upstream Contribution (Optional)
- Draft AGENTS.md template for Convex component packages
- Propose to Convex team via issue/PR on get-convex/workpool
- If adopted, update skill generator to merge upstream AGENTS.md
Prior Art
| Concept | Existing Example | Proposed Extension |
|---|---|---|
| Decision specs (PDRs) | delivery-process/decisions/pdr-*.feature |
New category: dependency-pattern |
| Source annotations | @libar-docs-uses (internal deps) |
@libar-docs-uses-external (npm packages) |
| Generated docs | docs-living/PATTERNS.md from annotations |
docs-living/DEPENDENCIES.md from annotations |
| Skills | ~/.claude/skills/convex-workpool/ (manual) |
Same location, generated from source |
| AGENTS.md | Not yet adopted | Upstream contribution candidate |
| llms.txt | 844K+ websites | Not applicable (web-only standard) |
| Context7 | 33K+ libraries indexed | Complementary — external index vs source-of-truth |
Context: Emerging Standards
The AI context ecosystem is converging but fragmented:
- AGENTS.md — Linux Foundation stewardship, 20+ tools (strongest convergence candidate)
- llms.txt — Website-level standard (844K+ sites), not applicable to npm packages
- Context7 — External index of 33K+ libraries via MCP, complementary approach
- Codebase Context Spec (.context/) — Proposed repo-level AI context directory
None of these solve the consumer-side annotation problem — documenting how YOUR codebase uses external dependencies. That's the unique contribution of this proposal.
Open Questions
- PDR granularity: One PDR per external package, or one per usage pattern? (e.g., "Workpool Usage" as one PDR vs. separate PDRs for "Workpool Dead Letters", "Workpool Partitioning", etc.)
- Annotation granularity: Annotate every import site, or only canonical/representative usages?
- Skill generation scope: Generate skills for all deps-packages, or only the heavily-used ones (workpool, workflow, agent)?
- Upstream timeline: Propose AGENTS.md to Convex team now (as early signal) or after proving the consumer-side approach?