Conversation
An agent in conversation meets write requests no action covers, and declaring more actions never closes that gap. This proposes enumerating the bounds instead of the writes: a 'writable' surface on the binding profile, default closed, written in the same concept/operation/fields vocabulary as 'affects' so admission is a subset test between two values of one type. A request plus the keys the agent resolved through lookups generates DML, which is parsed with the polyglot-sql engine already bundled for transpile.ts. Six AST checks admit it; the load-bearing one requires every UPDATE and DELETE to be keyed to a row a lookup resolved, so an unbounded write has no keys to bind. Constraints attach by what the statement touches rather than by a guards list -- a bounded carve-out to the rule that a constraint is inert until referenced, argued and flagged as a decision to make before building. Nothing writes without a person approving a proposal that names the change in ontology terms. A write that succeeded can graduate into an ordinary sql executor action, so the catalog grows from use. fork/constraint-eval is a prerequisite: its after-timing invariants are the only thing bounding the state a generated statement leaves behind.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposal only — no code. Adds
toolbox/mdcode/docs/semantic-model/freeform-actions.md. Supersedes and replaces #440, which is closed; nothing is carried over from it.An agent in conversation meets write requests no action covers, and declaring more actions never closes that gap — whatever is enumerated, the next sentence is outside it. So enumerate the bounds instead of the writes and generate the statement inside them at call time.
A
writablesurface on the binding profile. Default closed. Written in the sameconcept/operation/fieldsvocabulary asAffectedConcept, so admission is a subset test between two values of one type rather than a comparison between a declaration and some SQL. Writability is a physical facet, so it inherits and withdraws exactly asexecutorandsourcedo.Two-phase, always.
propose_change(request, refs)writes nothing and returns what it would do; a person approves;apply_changeruns the statements the proposal holds, not a regeneration. A declared action's DML was read by somebody before it shipped — a freeform statement has no such moment, so the moment is the call and the reviewer is the one asking.A six-check AST gate (
runtime/admit.ts), using the@polyglot-sql/sdkengine already bundled fortranspile.ts. The load-bearing check is that everyUPDATEandDELETEmust be keyed to a row a lookup already resolved. "Delete all orders" is well-formed DML inside any reasonable surface; what stops it is that no lookup resolved those rows, so there are no keys to bind. That rule is the difference between a bounded surface and a database connection.Constraints attach by what the statement touches, not by a
guardslist —AnalyzedRuleonfork/constraint-evalalready reports the entities and fields a rule reads. This reopens the settled rule that a constraint is inert until referenced. The argument for the carve-out is in the doc: that rule protects declared calls from a rule published later, and a freeform write is neither declared nor previously working, so nothing can regress. Declared actions' guards are untouched. Worth settling before anything is built.Graduation.
--save-asturns a freeform write that worked into an ordinarysqlexecutor action for review. Freeform is the long tail and the intake path, not a replacement — the catalog grows from what people asked for, and anything recurring stops being generated.fork/constraint-eval(79709b0) is a prerequisite rather than a neighbour: admission bounds which tables, columns, values and rows, and nothing in it says the resulting state is sound. Itsafter-timing invariants, which roll back inside the transaction, are the only thing that bounds a statement nobody wrote.