generated from coulomb/repo-seed
context loading, path resolution, form state, dynamic rules, and provider-neutral assessment runner/cache boundary
This commit is contained in:
@@ -9,9 +9,9 @@ Markdown as the authoring surface and uses fenced YAML as a structured extension
|
||||
for rules that need machine interpretation.
|
||||
|
||||
The first implementation is deterministic. It checks document type, fields,
|
||||
sections, ordering, metric bands, and text assertions. Forms, context, and LLM
|
||||
rubrics are represented in the contract vocabulary as extension points before
|
||||
runtime adapters are added.
|
||||
sections, ordering, metric bands, and text assertions. Runtime context, forms,
|
||||
dynamic rules, and provider-neutral assessment requests are implemented as
|
||||
extensions around the same contract vocabulary.
|
||||
|
||||
## Contract File Shape
|
||||
|
||||
@@ -112,10 +112,10 @@ fields, and metric bands. This is the bridge to later LLM rubrics: semantic
|
||||
checks can become additional assessments without changing how failures are
|
||||
reported.
|
||||
|
||||
## Forms And Context
|
||||
## Forms, Context, And Runtime Rules
|
||||
|
||||
Field specs are the first step toward form-backed Markdown generation. Runtime
|
||||
form handling should build on the same field vocabulary:
|
||||
Field specs are the foundation for form-backed Markdown generation and
|
||||
context-aware checks. Runtime form handling uses the same field vocabulary:
|
||||
|
||||
- `id`
|
||||
- `type`
|
||||
@@ -128,15 +128,25 @@ form handling should build on the same field vocabulary:
|
||||
- `min` / `max`
|
||||
- `min_length` / `max_length`
|
||||
|
||||
Dynamic requiredness, visibility, calculations, and prefill should be declared
|
||||
as context-aware rules in later work. The contract should remain the source of
|
||||
truth, while UI and generation layers act as adapters.
|
||||
Runtime context can be supplied as local YAML or JSON:
|
||||
|
||||
```text
|
||||
mkt contract check <document.md> --contract <contract.md> --context <context.yaml>
|
||||
mkt contract form-state <document.md> --contract <contract.md> --context <context.yaml>
|
||||
```
|
||||
|
||||
The runtime resolves fields in this order: document value, context source,
|
||||
default, missing. Document values win over context and conflicts are diagnostics.
|
||||
Dynamic rules support small deterministic `if` / `then` / `else` expressions
|
||||
for requiredness, visibility, allowed values, calculated values, context
|
||||
assertions, and dynamic section presence. See
|
||||
`docs/runtime-context-forms-assessments.md`.
|
||||
|
||||
## LLM Assessment Extension
|
||||
|
||||
LLM-assisted checks should be declared as rubrics, scoped to document or section
|
||||
roles. Core Markitect should not call a provider directly. A future adapter
|
||||
should accept a provider-neutral request:
|
||||
LLM-assisted checks are declared as rubrics, scoped to document or section roles.
|
||||
Core Markitect does not call a provider directly. It creates provider-neutral
|
||||
assessment requests for injected adapters:
|
||||
|
||||
- contract id and rule id
|
||||
- document or section text
|
||||
@@ -152,26 +162,11 @@ It should return:
|
||||
- model/provider metadata
|
||||
- diagnostics using the shared diagnostic model
|
||||
|
||||
## Deferred Runtime Work
|
||||
|
||||
The deterministic contract framework is ready now. The runtime engines are
|
||||
deferred to `MKTT-WP-0005-runtime-context-and-assessment-engines.md`.
|
||||
|
||||
Pick that work up when one of these becomes true:
|
||||
|
||||
- contract checks need external user, project, or entity context
|
||||
- generation needs reliable field prefill before rendering
|
||||
- a UI or agent workflow needs form state, defaults, and dynamic requiredness
|
||||
- deterministic section assertions are not enough and rubric-based semantic
|
||||
assessment becomes necessary
|
||||
|
||||
The intended order is context and form runtime first, deterministic dynamic
|
||||
rules second, LLM assessment execution third.
|
||||
|
||||
## CLI
|
||||
|
||||
```text
|
||||
mkt contract validate <contract.md>
|
||||
mkt contract check <document.md> --contract <contract.md>
|
||||
mkt contract check <document.md> --contract <contract.md> [--context <context.yaml>]
|
||||
mkt contract form-state <document.md> --contract <contract.md> [--context <context.yaml>]
|
||||
mkt metrics <document.md>
|
||||
```
|
||||
|
||||
@@ -34,6 +34,8 @@ framework organizes how Markitect itself exposes and composes capabilities.
|
||||
| `backend` | local SQLite index | snapshots/index/search storage |
|
||||
| `reference-provider` | section, region, fence, line | address in, content units out |
|
||||
| `validator` | schema, contract, section assertion | document/context in, diagnostics out |
|
||||
| `runtime` | context loader, form state, dynamic rules | document/contract/context in, diagnostics and state out |
|
||||
| `assessment-runner` | provider-neutral rubric execution | assessment request in, normalized result out |
|
||||
| `template-engine` | deterministic templates | template/data in, Markdown out |
|
||||
| `generation-adapter` | provider-neutral assisted generation | request in, generated candidate out |
|
||||
| `cli-group` | cache, backend, ref, class | command descriptors or registration hook |
|
||||
|
||||
@@ -72,7 +72,8 @@ This makes workflows useful without provider dependencies.
|
||||
| `transform` | transformed `markdown`, operations, provenance. |
|
||||
| `include` | include-resolved `markdown`, included paths, provenance. |
|
||||
| `contract_stub` | generated contract stub Markdown. |
|
||||
| `contract_check` | contract diagnostics and metrics. |
|
||||
| `contract_check` | contract diagnostics, metrics, and optional runtime context results. |
|
||||
| `form_state` | field values, origins, dynamic rule results, and diagnostics. |
|
||||
| `assisted` | generated Markdown if a hook is supplied, otherwise skipped/diagnostic. |
|
||||
|
||||
## Data Bindings
|
||||
|
||||
220
docs/runtime-context-forms-assessments.md
Normal file
220
docs/runtime-context-forms-assessments.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# Runtime Context, Forms, Rules, And Assessments
|
||||
|
||||
Date: 2026-05-04
|
||||
|
||||
## Purpose
|
||||
|
||||
The runtime layer turns contract extension points into executable behavior while
|
||||
keeping the deterministic contract framework intact. Static checks still handle
|
||||
document type, sections, assertions, and metric bands. Runtime checks add
|
||||
external context, field prefill, UI-neutral form state, dynamic rules, and a
|
||||
provider-neutral assessment protocol.
|
||||
|
||||
The layer is deliberately local-first. Core Markitect reads YAML or JSON context
|
||||
files and runs deterministic rules. Network calls, application lookups, and LLM
|
||||
providers belong behind adapters.
|
||||
|
||||
## Context Files
|
||||
|
||||
Runtime context can be a raw YAML/JSON mapping:
|
||||
|
||||
```yaml
|
||||
recipient:
|
||||
name: Ada Lovelace
|
||||
sender:
|
||||
name: Markitect Team
|
||||
```
|
||||
|
||||
or an envelope with metadata and schema:
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
case_id: case-42
|
||||
schema:
|
||||
type: object
|
||||
required: [recipient, sender]
|
||||
context:
|
||||
recipient:
|
||||
name: Ada Lovelace
|
||||
sender:
|
||||
name: Markitect Team
|
||||
```
|
||||
|
||||
The value under `context` is bound as `context` in field sources and dynamic
|
||||
rules. `schema` validates the full context object. `schemas` can validate named
|
||||
objects individually.
|
||||
|
||||
Malformed context and schema failures produce normal diagnostics:
|
||||
|
||||
- `runtime.context.malformed`
|
||||
- `runtime.context.schema_invalid`
|
||||
- `runtime.context.schema_target_missing`
|
||||
- `runtime.context.schema`
|
||||
|
||||
## Field Runtime
|
||||
|
||||
Field specs continue to live in the contract:
|
||||
|
||||
```yaml
|
||||
fields:
|
||||
recipient_name:
|
||||
type: string
|
||||
required: true
|
||||
source: context.recipient.name
|
||||
delivery_channel:
|
||||
type: string
|
||||
default: email
|
||||
enum: [email, print]
|
||||
```
|
||||
|
||||
Runtime resolution order is:
|
||||
|
||||
1. Manual document value from `path`, usually frontmatter.
|
||||
2. Context value from `source` or `sources`.
|
||||
3. Contract `default`.
|
||||
4. Missing.
|
||||
|
||||
Manual document values win over context. If both exist and differ, Markitect
|
||||
emits `runtime.field.conflict` as a warning by default. A field can set
|
||||
`conflict: error` to make that stricter. Multiple context sources with distinct
|
||||
values produce `runtime.field.ambiguous`.
|
||||
|
||||
`mkt contract check` uses runtime evaluation only when `--context` is supplied:
|
||||
|
||||
```text
|
||||
mkt contract check document.md --contract contract.md --context context.yaml
|
||||
```
|
||||
|
||||
`mkt contract form-state` always emits the UI-neutral runtime view:
|
||||
|
||||
```text
|
||||
mkt contract form-state document.md --contract contract.md --context context.yaml
|
||||
```
|
||||
|
||||
## Form State
|
||||
|
||||
Form state is not a UI framework. It is a stable contract that future UIs,
|
||||
agents, generators, and workflow steps can render:
|
||||
|
||||
- field id
|
||||
- value
|
||||
- origin: `manual`, `prefilled`, `defaulted`, `calculated`, or `missing`
|
||||
- required/optional
|
||||
- visible/hidden
|
||||
- enabled/disabled
|
||||
- allowed values
|
||||
- diagnostics
|
||||
- metadata
|
||||
|
||||
Hidden fields are not required unless a future adapter explicitly asks for
|
||||
hidden validation. This matches practical form behavior and avoids punishing
|
||||
authors for data that the current context made irrelevant.
|
||||
|
||||
## Dynamic Rules
|
||||
|
||||
Rules are deterministic YAML. They use a deliberately small condition language:
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
- id: postal-address-for-print
|
||||
if:
|
||||
path: fields.delivery_channel.value
|
||||
equals: print
|
||||
then:
|
||||
required: [postal_address]
|
||||
visible:
|
||||
postal_address: true
|
||||
else:
|
||||
hidden: [postal_address]
|
||||
```
|
||||
|
||||
Supported condition operators:
|
||||
|
||||
- `exists`
|
||||
- `equals` / `eq`
|
||||
- `not_equals`
|
||||
- `in`
|
||||
- `contains`
|
||||
- `matches`
|
||||
- `gt`, `gte`, `lt`, `lte`
|
||||
- `all`, `any`, `not`
|
||||
|
||||
Supported actions:
|
||||
|
||||
- `required` / `optional`
|
||||
- `visible` / `hidden`
|
||||
- `enabled` / `disabled`
|
||||
- `allowed_values`
|
||||
- `set`
|
||||
- `assert`
|
||||
- `sections`
|
||||
|
||||
Calculated values can reference runtime paths:
|
||||
|
||||
```yaml
|
||||
then:
|
||||
set:
|
||||
contact_label: "${fields.sender_name.value} <${context.sender.email}>"
|
||||
```
|
||||
|
||||
Context assertions use the same condition vocabulary:
|
||||
|
||||
```yaml
|
||||
assert:
|
||||
path: context.sender.email
|
||||
matches: "@example\\.com$"
|
||||
message: Sender email must come from example.com.
|
||||
severity: warning
|
||||
```
|
||||
|
||||
Dynamic section rules are intentionally narrow. They can require, recommend,
|
||||
discourage, or forbid section specs already declared in the contract.
|
||||
|
||||
## Assessment Protocol
|
||||
|
||||
Rubrics remain provider-neutral contract declarations:
|
||||
|
||||
```yaml
|
||||
rubrics:
|
||||
- id: tone-fit
|
||||
scope: section.body
|
||||
criteria: The body should match the recipient relationship.
|
||||
threshold: 0.75
|
||||
```
|
||||
|
||||
Core Markitect turns rubrics into `AssessmentRequest` objects and normalizes
|
||||
adapter results into `AssessmentResult` and diagnostics. It does not call an LLM
|
||||
provider directly. The cache key includes contract id, rule id, scope, text,
|
||||
criteria, context, structured inputs, threshold, provider, model, and metadata.
|
||||
|
||||
Adapters can be injected from workflows, applications, or tests. A transparent
|
||||
in-memory cache exists for tests and short runs; persistent storage remains a
|
||||
backend concern.
|
||||
|
||||
## Workflow Integration
|
||||
|
||||
Workflow `contract_check` steps accept `context`:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- id: check-letter
|
||||
kind: contract_check
|
||||
document: letter.md
|
||||
contract: letter.contract.md
|
||||
context: letter.context.yaml
|
||||
```
|
||||
|
||||
Workflow `form_state` steps expose the runtime state as a step result:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- id: form
|
||||
kind: form_state
|
||||
document: letter.md
|
||||
contract: letter.contract.md
|
||||
context: letter.context.yaml
|
||||
```
|
||||
|
||||
This keeps workflow orchestration separate from the runtime engine. The runtime
|
||||
engine answers "what does this contract imply in this context"; the workflow
|
||||
engine decides when to run it and where to send the output.
|
||||
@@ -188,7 +188,8 @@ First implementation step kinds:
|
||||
| `transform` | Apply deterministic Markdown transforms. |
|
||||
| `include` | Resolve include markers in Markdown. |
|
||||
| `contract_stub` | Generate a Markdown stub from a contract. |
|
||||
| `contract_check` | Check a Markdown document against a contract. |
|
||||
| `contract_check` | Check a Markdown document against a contract, optionally with runtime context. |
|
||||
| `form_state` | Evaluate UI-neutral field prefill, validation, and dynamic rules. |
|
||||
| `assisted` | Provider-neutral assisted step boundary, optional by default. |
|
||||
|
||||
## Data Bindings
|
||||
|
||||
@@ -35,7 +35,7 @@ and descriptions mirror the operational view.
|
||||
| `MKTT-WP-0010` | complete | done | `MKTT-WP-0004`; task-level trigger: `MKTT-WP-0003-T006` | Content references, processors, explode/implode, weave/tangle, content classes, and migration examples are complete as the first WP-0010 extension layer. |
|
||||
| `MKTT-WP-0007` | complete | done | `MKTT-WP-0006` | Advanced query and local index backend is complete: AST inspection, optional JSONPath, SQLite snapshots/metadata, FTS5 search, incremental refresh, and local index CLI. |
|
||||
| `MKTT-WP-0013` | complete | done | `MKTT-WP-0003`, `MKTT-WP-0004`, `MKTT-WP-0006`, `MKTT-WP-0007`, `MKTT-WP-0010` | Internal extension framework is complete: characterization tests, canonical processing model, descriptors, registries, lifecycle callbacks, query-engine registry, built-in extension catalog, CLI command specs, and authoring guide. |
|
||||
| `MKTT-WP-0005` | P2 | todo | `MKTT-WP-0003`, `MKTT-WP-0004` | Pick up when generation/form/context or semantic assessment pressure appears. |
|
||||
| `MKTT-WP-0005` | complete | done | `MKTT-WP-0003`, `MKTT-WP-0004` | Runtime context, form state, dynamic rules, workflow integration, and provider-neutral assessment boundary are complete. |
|
||||
| `MKTT-WP-0011` | complete | done | `MKTT-WP-0003`; task-level triggers: `MKTT-WP-0010-T001`, `MKTT-WP-0010-T005` | Markdown dataflow workflow layer is complete: workflow standard, source collectors, binding model, deterministic steps, assisted boundary, safe outputs, CLI, docs, and examples. |
|
||||
| `MKTT-WP-0009` | P2 | todo | `MKTT-WP-0006` | Establish access-control gateway before security-sensitive cache/context use. |
|
||||
| `MKTT-WP-0012` | P3 | todo | `MKTT-WP-0004`, `MKTT-WP-0010`, `MKTT-WP-0011` | Future Quarkdown-inspired document function layer: reusable Markdown-native function calls over processors, references, contracts, workflows, and later assisted steps. |
|
||||
|
||||
Reference in New Issue
Block a user