nexg-erp / Forms
Vocabulary
The clauses, in plain words

beta/docs/vocabulary.md

The words this project uses.

The words this project uses, so every conversation starts on shared language. An entry defines the word and points to the document that owns it. Facts, numbers and specs stay in the owning documents; the moment an entry carries a measurement, it is a second place for that fact to drift. When a new term gets coined in a design or a worklog, it gets an entry here in the same MR.

80 terms

The trees

5
study

the Oracle Forms feasibility work in study/. The converter, the runtime, and seven forms converted end to end. Still builds, still deploys.

hello-flux

the research phase, another project's tree kept here so citations resolve. Read it and cite it, never edit it.

beta

the product, a multi-tenant SaaS over the same converter. Design in beta/docs/.

corpus

the FMB XMLs under study/xml/ and everything measured from them: triggers, program units, items, LOVs. Sample forms until Green Waste's own arrive.

EB-1

hello-flux's parked rules-engine design, the source of the value contract and the evaluator's guarantees. Design only, never implemented there.

The language

31
CRL

the Clause Rule Language, in which all converted business logic is expressed and which is the only thing that runs. Owned by clause.md.

clause

the unit of CRL, where the name comes from.

CRL program

a complete CRL unit as stored in a FormSpec's rules, one trigger's worth of clauses. Always written with the prefix. Forms calls its own unit of PL/SQL a program unit, so a bare "program" is one word away from meaning the other thing.

effect

one of the five things a clause can do: state, message, abort, navigate, report. The alphabet is closed, and closed is the point.

abort

the effect that stops the operation, written deny at the top of a clause and as an abort inside a nested branch. Named for what RAISE FORM_TRIGGER_FAILURE does, which is to end the operation while displaying nothing.

trigger point

when a program runs: on change, on save, on press, on load, and the rest of the collapsed Forms events.

advisory / blocking

the difference between change and save. A change rule is advisory: it shows a message, marks a field invalid, and blocks nothing. A save rule is blocking: it refuses the write and rolls the transaction back. CRL must never blur them.

terminates

every CRL program finishes, by construction. What buys static verification, transaction safety, browser execution and a checkable translation target. The type-theory name is total, kept in clause.md where it is defined and avoided elsewhere: this is a ledger product, and a running total is a different thing entirely.

collection operation

one of the six set-based operations CRL has instead of a loop keyword. Owned by crl-loops.md.

canonical form

the JSON AST, which is what is stored, executed and verified. The text syntax is a projection of it, deferred until the rule editor needs it.

key table

the one key order for the whole language, in crl/golden/README.md. One table rather than one order per node type, so a writer needs no type dispatch and two writers cannot disagree about a node they classify differently.

the fixed point

the property that the schema accepts exactly what the serializer emits, so parsing a document and serializing it again returns the same bytes. It is why a schema lenient where the serializer normalizes is a defect and not a convenience.

ratify

what the zod schema does to the frozen encoding rather than replace it. A rule the encoding already stated is re-expressed in a second form, never re-decided.

value contract

the typed values every program is evaluated under: Decimal, split date and dateTime, strings on the wire. Owned by september/04-value-contract.md, adopted from EB-1.

EvalEnv

the injected environment, clock and tenant timezone, so the evaluator never reads the system clock. Determinism as a guarantee, not a convention.

stdlib

CRL's small set of pure functions and operators, taken from corpus usage.

isolated Decimal

the cloned decimal.js constructor all CRL arithmetic goes through, pinned to one precision and to Oracle's rounding. The global Decimal is never the one doing the arithmetic.

coercion boundary

the one place a page string becomes a typed value, and therefore the one place blankness is decided. Nothing downstream trims.

strings on the wire

every value travels as text. crlVersion is the only JSON number the language has.

absent operand

a key the caller did not send, which means the rule could not be evaluated. Not the same as a blank one, which means the user left the field empty.

fails closed

what a blocking point does with an absent operand, which is refuse. The alternative reads a check that never ran as a check that passed.

could not be evaluated

the outcome beside valid, refused and no verdict, carried as the evaluator's error. It always comes with an invalid verdict, because a value nothing could read must never let a blocking check through.

isomorphic

no Node API, no DOM and no framework, so the same code runs in a browser, on a server and in a test. A constraint on @valko/crl that a test enforces by reading the source, not a preference.

the seam

study/lib/ruleEngine.ts, now a re-export of the package. The one place the study adapts to a type the package keeps deliberately narrower than the study's own.

the two vocabularies

the package surface carries both the study engine's eight rule kinds and CRL's twenty clause kinds. Sprint 3 retires the older one; until then a consumer of either finds it in one place.

run report

the effect that runs an Oracle report, always written in full. A bare "report" in this project is a document: the coverage report, a bug report.

call

CRL's one escape hatch, routing to a ported program unit or a captured package. A target that is neither becomes a gap.

set

the clause that writes, into the record under evaluation or into session state. Not one of the five effects, which act outside the record. What the study's populate and compute both became.

connective

and, or or not, combining guards. Distinct from the eleven operators, which combine values. not is the negation of a guard being true, so it fires where PL/SQL's Else fired, on false and on null alike. Listed in clause.md.

system state

Forms' own runtime values, Record_Status, Form_Status, Cursor_Record and Last_Record. A read-only namespace of its own, never a session global, and closed: a fifth name needs a corpus site.

form parameter

an argument the form was called with, read through a parameter node and never written. A fifth namespace beside page fields, session globals, lookup columns and system state, and not the Forms parameter list, whose handles the platform supersedes. Listed in clause.md.

The converter

26
recognizer

a closed matcher that turns one Forms idiom into CRL. It never interprets mechanics and never guesses; an unmatched shape is refused.

refused

the third outcome beside pass and fail, and correct behaviour, not failure. A refusal becomes a gap. If refusals score as failures, the pressure is to convert unsafely.

gap

what did not convert, carried in the FormSpec with its source text and fingerprint. The customer-facing worklist, not an appendix.

fingerprint

the normalized hash of a refused shape, so one procedure copied seven times files one report, not seven.

path gate

emit a claimed effect only when every enclosing guard on its path is also claimed. The narrowing of the all-claimed gate that keeps its safety argument.

all-claimed

the study's original gate: one unclaimed node refuses the whole trigger. Correct about ancestors, stronger than needed about siblings.

claim

what a recognizer does to a statement it understands, which is take responsibility for it. A claimed statement becomes a clause or is consumed; an unclaimed one becomes a gap. A recognizer that claims a statement and emits nothing for it is the one failure the coverage rule exists to catch.

consumed

a claim that produces no clause, because the statement is half an idiom whose other half carries the meaning, or an explicit do-nothing. A NULL; is consumed and a SELECT COUNT(*) feeding an exists is consumed.

the path gate as data

how a nested raise is stored. There is no if clause; the enclosing guards are conjoined into the clause's own when, so the gate's rule is a shape in the document rather than a step in the converter.

cover / the coverage rule

every non-blank statement of a trigger's body is accounted for by a gap that quotes it, a clause that reads it, a value help on the field, or being a bare NULL;. Nothing may be none of the four.

silent drop

a statement that is none of the four. Work the converter neither did nor put on the worklist, and the one failure a coverage number cannot show, because a dropped statement makes the converted fraction look better rather than worse.

check source

the data source whose row a program's row-reading clauses read, named once on the program in lookup rather than per clause, because one Forms trigger reads one row. Id-prefixed check-, against a value help's lov- and a block's records-.

crowded point

an owner carrying more than one Forms event that collapses to the same trigger point, which 82 of the corpus's 529 programs are in. Both members name their event in the id, so which came first in the document decides nothing.

opener button

a control whose whole job is to open a field's value list, the small torch Forms put beside a field. Read from its trigger body and never from its name, and recorded as forms.opensValueList on the button's own field, so it converts to neither a program nor a gap.

golden set

the hand-translated CRL programs, the 29 verified plus the stress set, that the evaluator and the converter are tested against. Lives in beta/crl/, and crl/golden/README.md owns its JSON encoding.

golden program

one member of that set: one file, one trigger point, its clauses in evaluation order, the PL/SQL it was read from, and the cases it is expected to satisfy.

verified translation / stress translation

the two halves of the golden set. A verified translation is read from an existing verified test and names it. A stress translation is written against a corpus body picked for what the verified half never exercises, and has no test behind it, which is why it names none.

the guard

the golden set's own check, beta/crl/golden/golden.test.mjs. It holds every golden file to the encoding and carries a second implementation of the serialization rules on purpose, because byte-for-byte determinism rests on two writers agreeing.

harness

the one door anything asks what a CRL program does through, in beta/crl/src/harness/. Four doors rather than one, because the trigger point decides how an absent operand reads. Never a fixture: a fixture lets a verification pass while the thing it stands for refuses the user's own choice.

catalogue

the programs a harness looks up in, supplied by its caller. The golden set off disk this month and a FormSpec's rules in sprint 3, with no change to the interface between them.

cannot drive

of an expect case, that the evaluator cannot reach its stated outcome because the encoding carries no input for something the program reads. A case is marked with its reason, run anyway, counted, and fails the golden runner the day it becomes drivable.

subset assertion

how the golden runner reads outcome.values. A case may name fewer fields than the program wrote, so the fields it names must match and the rest are not asserted.

verified

a rule counts as verified only when a test reads its expectation from the source PL/SQL quoted in its own docstring. The discipline the whole metric rests on.

superseded

classified as converting to nothing because the platform already does the job, like Forms' master-detail plumbing and the form lifecycle calls. Not a gap, not a failure.

capture / uncaptured

a database package's source taken through /api/db/query, or not yet. An unresolved name is usually an uncaptured package, not a parser bug.

determinism

same XML in, same output out, byte for byte, with the converter's clock injected. Asserted in CI.

The document

5
FormSpec

one converted form as one document: sources, blocks, fields, rules, gaps. Owned by formspec.md.

role

what a field is, not which widget drew it in 1998, carried as role on the field. The renderer decides the component; Oracle specifics stay in the forms block that nothing else reads. Never "control", which Forms already spends on a control block, a block with no table behind it.

value help

a query-backed picker on a field. A pick is a patch to the record, not a value returned to one input.

data source

a declared, named query in the FormSpec. Components call it by id and never compose SQL.

component registry

the map from role to component the renderer resolves through. Its widened context is the second contract formspec.md owns.

The product

6
Oracle-connected account

the SaaS reads and writes the customer's existing Oracle. The only account type the beta ships.

the upsell

the PostgreSQL migration that ends the customer's Oracle licence fee. Designed for, not built. The reason logic must live in CRL and never in PL/SQL.

engineering mode

the mode whose changes alter the tenant's data model, uploads and the rule editor included. Distinct from admin-gating, which is permission, not mode.

app mode

where daily work happens over the model engineering mode defines.

rule editor

where a human completes the worklist the converter could not. Layer 2, out of the September scope.

worklist

what remains for a human after conversion: the gaps, in editable form.

The process

7
worklog

the per-item record of what was done, found, decided and left open, under beta/docs/september/. It never restates a spec.

a fact lives in one document

the discipline this vocabulary also obeys. A fact stated twice drifts in both places.

item

one row of the September plan, the unit of status, and nothing else. Forms calls a field an item, so in beta/ the Forms construct is always a field. The count lives in formspec.md, which owns it.

sprint / phase / task

the sequencing of items in september/sprints.md: a sprint holds phases, a phase holds tasks, and a task references its item.

checkpoint

the dated condition a sprint ends at, defined in the September README. Not a gate, which is a converter's safety filter, as in the path gate.

the freeze

the checkpoint where the vocabulary stops moving, so the AST is designed against a settled language. After it, a shape the corpus needs is the converter's problem and a gap, not a word added to clause.md.

the spine

the full path from XML through FormSpec and CRL to an evaluated verdict. What the September deliverable proves end to end.

Four terms are load-bearing: advisory / blocking, refused, superseded and verified. Each carries a safety distinction rather than a shade of meaning, so using one loosely does not merely miscommunicate, it specifies a defect.

The markdown file is the record and this page is a reader. An entry defines the word and points to the document that owns it; facts and numbers stay in the documents that own them.