Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
332 changes: 244 additions & 88 deletions src/agent/resources/tools/curate.txt

Large diffs are not rendered by default.

41 changes: 39 additions & 2 deletions src/server/core/domain/render/element-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,49 @@
*/

/**
* The five M1 element names. Adding to this list must be an additive
* operation; downstream consumers iterate the registry generically.
* The M1 element names. The HTML curate format must round-trip through
* the markdown writer without information loss; the vocabulary covers
* everything the writer renders into the `.md` file:
*
* bv-topic — root container; carries frontmatter as attributes.
* bv-reason — `## Reason` body section.
* bv-task, — `## Raw Concept` sub-fields:
* bv-changes, Task / Changes / Files / Flow / Timestamp /
* bv-files, Author / Patterns. (One sibling per emitted
* bv-flow, bullet-label; multiple <bv-pattern> permitted.)
* bv-timestamp,
* bv-author,
* bv-pattern
* bv-structure, — `## Narrative` sub-fields:
* bv-dependencies, Structure / Dependencies / Highlights /
* bv-highlights, Rules / Examples / Diagrams.
* bv-rule,
* bv-examples,
* bv-diagram
* bv-fact — `## Facts` list entry (subject/category/value attrs).
* bv-decision — net-new in M1: decision record.
* bv-bug, bv-fix — net-new in M1: paired bug + fix runbook entries.
*
* Adding to this list must be an additive operation; downstream
* consumers iterate the registry generically.
*/
export const ELEMENT_NAMES = [
'bv-topic',
'bv-reason',
'bv-task',
'bv-changes',
'bv-files',
'bv-flow',
'bv-timestamp',
'bv-author',
'bv-pattern',
'bv-structure',
'bv-dependencies',
'bv-highlights',
'bv-rule',
'bv-examples',
'bv-diagram',
'bv-fact',
'bv-decision',
'bv-bug',
'bv-fix',
Expand Down
10 changes: 10 additions & 0 deletions src/server/infra/render/elements/bv-author/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-author>` attributes.
*
* Renders as `**Author:**` inside the `## Raw Concept` section — the
* person or system identifier responsible for the concept. Free-form
* string content.
*/
export const BvAuthorAttributesSchema = z.object({}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-author/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvAuthorAttributesSchema} from './schema.js'

export const validateBvAuthor = makeAttributeValidator('bv-author', BvAuthorAttributesSchema)
10 changes: 10 additions & 0 deletions src/server/infra/render/elements/bv-changes/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-changes>` attributes.
*
* Renders as `**Changes:**` inside the `## Raw Concept` section — a
* list of changes (code, process, decision). Children should be `<li>`
* items; the writer flattens them into a markdown list.
*/
export const BvChangesAttributesSchema = z.object({}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-changes/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvChangesAttributesSchema} from './schema.js'

export const validateBvChanges = makeAttributeValidator('bv-changes', BvChangesAttributesSchema)
10 changes: 10 additions & 0 deletions src/server/infra/render/elements/bv-dependencies/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-dependencies>` attributes.
*
* Renders as the `### Dependencies` subsection inside `## Narrative` —
* dependencies, prerequisites, blockers, or relationship information.
* No attributes.
*/
export const BvDependenciesAttributesSchema = z.object({}).passthrough()
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvDependenciesAttributesSchema} from './schema.js'

export const validateBvDependencies = makeAttributeValidator('bv-dependencies', BvDependenciesAttributesSchema)
14 changes: 14 additions & 0 deletions src/server/infra/render/elements/bv-diagram/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-diagram>` attributes.
*
* Renders verbatim into the `### Diagrams` subsection — preserves
* mermaid / plantuml / ascii / dot diagrams character-for-character
* (per the curate detail-preservation contract). The `type` attribute
* tells the writer which fenced-code-block language tag to emit.
*/
export const BvDiagramAttributesSchema = z.object({
title: z.string().optional(),
type: z.enum(['mermaid', 'plantuml', 'ascii', 'dot', 'graphviz', 'other']).optional(),
}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-diagram/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvDiagramAttributesSchema} from './schema.js'

export const validateBvDiagram = makeAttributeValidator('bv-diagram', BvDiagramAttributesSchema)
9 changes: 9 additions & 0 deletions src/server/infra/render/elements/bv-examples/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-examples>` attributes.
*
* Renders as the `### Examples` subsection inside `## Narrative` —
* worked examples, sample code, or scenario walkthroughs. No attributes.
*/
export const BvExamplesAttributesSchema = z.object({}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-examples/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvExamplesAttributesSchema} from './schema.js'

export const validateBvExamples = makeAttributeValidator('bv-examples', BvExamplesAttributesSchema)
26 changes: 26 additions & 0 deletions src/server/infra/render/elements/bv-fact/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-fact>` attributes.
*
* Renders as a `## Facts` list entry. Mirrors the existing structured-fact
* model (statement / category / subject / value):
* <bv-fact subject="user_name" category="personal" value="Andy">
* My name is Andy.
* </bv-fact>
* The element's text content is the canonical statement; attributes are
* the structured extraction.
*/
export const BvFactAttributesSchema = z.object({
category: z.enum([
'personal',
'project',
'preference',
'convention',
'team',
'environment',
'other',
]).optional(),
subject: z.string().optional(),
value: z.string().optional(),
}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-fact/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvFactAttributesSchema} from './schema.js'

export const validateBvFact = makeAttributeValidator('bv-fact', BvFactAttributesSchema)
10 changes: 10 additions & 0 deletions src/server/infra/render/elements/bv-files/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-files>` attributes.
*
* Renders as `**Files:**` inside the `## Raw Concept` section — a list
* of related source files, documents, URLs, or references. Children
* should be `<li>` items.
*/
export const BvFilesAttributesSchema = z.object({}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-files/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvFilesAttributesSchema} from './schema.js'

export const validateBvFiles = makeAttributeValidator('bv-files', BvFilesAttributesSchema)
9 changes: 9 additions & 0 deletions src/server/infra/render/elements/bv-flow/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-flow>` attributes.
*
* Renders as `**Flow:**` inside the `## Raw Concept` section — the
* process flow, workflow, or sequence of steps. No attributes.
*/
export const BvFlowAttributesSchema = z.object({}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-flow/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvFlowAttributesSchema} from './schema.js'

export const validateBvFlow = makeAttributeValidator('bv-flow', BvFlowAttributesSchema)
10 changes: 10 additions & 0 deletions src/server/infra/render/elements/bv-highlights/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-highlights>` attributes.
*
* Renders as the `### Highlights` subsection inside `## Narrative` —
* key highlights, capabilities, deliverables, or notable outcomes.
* No attributes.
*/
export const BvHighlightsAttributesSchema = z.object({}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-highlights/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvHighlightsAttributesSchema} from './schema.js'

export const validateBvHighlights = makeAttributeValidator('bv-highlights', BvHighlightsAttributesSchema)
16 changes: 16 additions & 0 deletions src/server/infra/render/elements/bv-pattern/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-pattern>` attributes.
*
* Renders as a bullet entry inside `**Patterns:**` (under `## Raw Concept`).
* The pattern itself is the element's text content; structured fields
* (flags, description) are attributes. Multiple `<bv-pattern>` siblings
* inside `<bv-topic>` are collected into a single bullet list.
*
* <bv-pattern flags="g" description="Match an email">[\w.+-]+@[\w.-]+</bv-pattern>
*/
export const BvPatternAttributesSchema = z.object({
description: z.string().optional(),
flags: z.string().optional(),
}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-pattern/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvPatternAttributesSchema} from './schema.js'

export const validateBvPattern = makeAttributeValidator('bv-pattern', BvPatternAttributesSchema)
10 changes: 10 additions & 0 deletions src/server/infra/render/elements/bv-reason/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-reason>` attributes.
*
* Renders as the `## Reason` body section in the .md writer — the
* curate operation's "why" stated for a human reviewer. Has no
* attributes; the body text is the rendered content.
*/
export const BvReasonAttributesSchema = z.object({}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-reason/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvReasonAttributesSchema} from './schema.js'

export const validateBvReason = makeAttributeValidator('bv-reason', BvReasonAttributesSchema)
10 changes: 10 additions & 0 deletions src/server/infra/render/elements/bv-structure/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-structure>` attributes.
*
* Renders as the `### Structure` subsection inside `## Narrative` —
* structural or organizational documentation (file layout, process
* hierarchy, timeline). No attributes.
*/
export const BvStructureAttributesSchema = z.object({}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-structure/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvStructureAttributesSchema} from './schema.js'

export const validateBvStructure = makeAttributeValidator('bv-structure', BvStructureAttributesSchema)
9 changes: 9 additions & 0 deletions src/server/infra/render/elements/bv-task/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-task>` attributes.
*
* Renders as `**Task:**` inside the `## Raw Concept` section — the
* subject/task this concept relates to. No attributes.
*/
export const BvTaskAttributesSchema = z.object({}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-task/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvTaskAttributesSchema} from './schema.js'

export const validateBvTask = makeAttributeValidator('bv-task', BvTaskAttributesSchema)
11 changes: 11 additions & 0 deletions src/server/infra/render/elements/bv-timestamp/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {z} from 'zod'

/**
* Zod schema for `<bv-timestamp>` attributes.
*
* Renders as `**Timestamp:**` inside the `## Raw Concept` section — the
* date the concept's data represents (distinct from the file's
* createdAt/updatedAt frontmatter, which is system-set). Free-form
* string content (typically ISO-8601 or short date).
*/
export const BvTimestampAttributesSchema = z.object({}).passthrough()
4 changes: 4 additions & 0 deletions src/server/infra/render/elements/bv-timestamp/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {makeAttributeValidator} from '../make-validator.js'
import {BvTimestampAttributesSchema} from './schema.js'

export const validateBvTimestamp = makeAttributeValidator('bv-timestamp', BvTimestampAttributesSchema)
41 changes: 16 additions & 25 deletions src/server/infra/render/elements/bv-topic/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,27 @@ import {z} from 'zod'
/**
* Zod schema for `<bv-topic>` attributes.
*
* HTML attributes arrive as strings. Numeric and enum constraints are
* expressed via regex + refine, since HTML never gives us native numbers.
* `<bv-topic>` carries the topic file's frontmatter as attributes. The
* markdown writer maps these directly to YAML frontmatter on disk.
*
* Notably absent: `importance`, `maturity`, `recency`, `updatedat`,
* `createdAt`. Per the runtime-signals migration (research/features/
* runtime-signals/), ranking signals are *sidecar* state — per-user,
* per-machine — not file content. Including them as attributes here
* would re-introduce the noise-from-implicit-state problem the
* migration solved. The system writes timestamps; the LLM does not.
*
* `passthrough` is intentional: M1 is permissive on unknown attributes
* (parse-and-skip — no warning is emitted). Strict validation per
* ADR-007 §13 is M2 work.
*/
export const BvTopicAttributesSchema = z.object({
importance: z
.string()
.regex(/^\d+$/, {message: 'importance must be an integer string "0".."100"'})
.refine((v) => {
const n = Number(v)
return n >= 0 && n <= 100
}, {message: 'importance must be in [0, 100]'})
.optional(),
maturity: z.enum(['draft', 'validated', 'core']).optional(),
// Comma-separated lists are the natural HTML-attribute encoding for
// arrays. The writer splits on `,` and trims; empty list is `""`.
keywords: z.string().optional(),
path: z.string().min(1, {message: 'path is required and must be non-empty'}),
recency: z
.string()
.regex(/^\d+(\.\d+)?$/, {message: 'recency must be a numeric string'})
.refine((v) => {
const n = Number(v)
return n >= 0 && n <= 1
}, {message: 'recency must be in [0, 1]'})
.optional(),
// Lowercase per HTML5 attribute-name normalization (parse5 lowercases
// `updatedAt="..."` to `updatedat`; schema keys must match the parser
// output, not the source HTML). See element-types.ts attribute-case note.
// `offset: true` accepts explicit timezone offsets like `+02:00` (e.g.
// from `git log --date=iso-strict`), not only `Z`.
updatedat: z.string().datetime({message: 'updatedat must be ISO-8601 datetime', offset: true}).optional(),
related: z.string().optional(),
summary: z.string().optional(),
tags: z.string().optional(),
title: z.string().min(1, {message: 'title is required and must be non-empty'}),
}).passthrough()
Loading
Loading