ReferenceOperatorsbusiness.decide

business.decide

Generated by docs/scripts/generate-docs.mjs from operators/business-decide/operator.md and operators/business-decide/operator.json. Edit the source, not this page.

Binding

FieldValue
idbusiness.decide
domainbusiness
resources.profilesol-fresh
resources.requires
policy.webSearch
policy.grammarBound
policy.imageGeneration

Job

Decide and publish one evidence-backed business promise as durable backend-owned authority, frozen behind a complete promise-to-enforcement coverage matrix, or reconcile that published head against the source that was actually delivered.

Two modes, one head

mode decides which half of this operator runs. Under model the promise is modelled and the coverage matrix is frozen: steps 4, 5 and 6 run and the branch writes response/data/coverage-matrix.json. Under reconcile nothing is modelled again; step 7 compares the head that was already published against the source a backend run delivered, and the Input backend-source-application is required in that mode, because a reconciliation with no delivered source is an opinion about code nobody read. The Inputs table marks it optional because the requirement is conditional, and validate.mjs refuses a reconcile branch whose request does not bind it. Both modes end at the same place: one head under @worktrees/businesses/<featureId> and one response/data/model.json that says exactly what that head now holds.

A first run starts from the person’s promise

A feature that no source implements yet has no fact claim by construction. On a first run under mode model, the promise the person stated in promise is recorded as the one intent claim, bound to request/request.json#requirements.promise instead of a source line, and the model is built from it; EVIDENCE_MISSING applies to a fact claim without a file behind it, never to the intent of a promise that is being decided for the first time. Every enforcing row of the coverage matrix still rests on a fact claim, so a greenfield head publishes with its enforcing rows open, which is what pending means.

Separate the claim before modelling it

Modelling begins by separating every observation into fact, intent, example, unknown, or contradiction, and that separation is written to response/data/claims.json before anything is modelled from it. The separation exists to make one substitution impossible: an example, a screenshot, or an owner’s intent illustrates a promise, and only an observed fact in routed source proves that the promise is enforced. A coverage row that asserts enforcement therefore cites at least one fact claim, and every fact claim binds the observed source head. A claim that cites a source nobody bound is invalid input rather than a warning, because an unbound citation cannot be told apart from an invented one. Two claims that disagree about the same behaviour are never averaged into a middle reading; the contradiction stops the invocation and returns to its owner.

No promise without coverage

A promise is publishable only when every dimension the request declared carries exactly one disposition, and every consumer and lifecycle branch the operator discovered is disposed by name. dimensions defaults to the dimensions of the previous head, which is why it is required on a first run: the first publication is the one that decides what the promise is even accountable for. That rule exists because “full access” was modelled, implemented, and published while its course, community, blog, AI, mock-interview, legacy-sale, quota, settlement, renewal, cancellation, and recovery consumers had never all been proved. The promise was true in the offer and false at the guard. Four prohibitions carry the repair, and each is enforced rather than advised. A discovered consumer with no matrix row is CONSUMER_UNPROVEN. A mandatory dimension, meaning actor and eligibility, offer entry, read entry, purchase side effect, settlement, idempotency, entitlement consumer, and denial, can never be marked not applicable when it was declared. A dimension whose branch was observed in source can never be marked not applicable either, because it was found, so it applies. A preserve or replace disposition without a negative proof is rejected, since positive proof alone shows the promise is granted and never that it is denied when it should be.

The dispositions and what each one must carry

preserve keeps the existing enforcement and carries owner, source, positive proof, negative proof, and one fact claim. replace changes the enforcement and carries the same substance for the new path. retire closes a path on purpose and carries owner, source, proof the path is closed, and one fact claim. defer postpones a branch to a named owner, carries a deferral reference, and carries no proof at all, because proof for work that has not happened is the most convincing kind of false pass. not-applicable states the branch cannot occur and carries nothing: no owner, no source, no proof, no consumer, no claim. defer is a disposition, so a deferred branch does not block publication; what blocks publication is silence.

One flat authority root

One feature owns exactly one head directory, <businesses root>/features/<featureId>, whose model.json is the head, and step 8 takes an exclusive lease on that alias before it writes. Two branches of the same step may not publish the same feature. features/ is the only segment between the root and a feature: a project segment inserted below the root starts a second authority tree that later readers never find, so any head that is not exactly features/<featureId> is refused. The head is classified absent, fresh, or stale against the frozen evidence and the frozen source head, and that classification decides which lifecycle transition is legal. Rejection preserves lineage by naming the previous head rather than erasing it, and implemented is never published on the strength of a plan: delivered source is compared against the frozen matrix first, under reconcile.

Boundary

Context is read-only apart from the one feature head. The operator writes only response/ of its own branch, response.md, response/data/claims.json, response/data/coverage-matrix.json under mode model, response/data/model.json and response.json, plus the one feature head under @worktrees/businesses/<featureId>. It never publishes a promise while a discovered consumer or lifecycle branch carries no disposition, promotes an example, a screenshot, or an intent claim into product truth, invents an actor, entitlement, quota, payment, settlement, or lifecycle behaviour the evidence does not state, advances a head through a transition the lifecycle does not allow, or writes a head below a project segment under the businesses root. It does not modify product source, architecture authority, frontend authority, or backend implementation, and it never claims that an implementation, a quality gate, or a UAT run has passed.

Context

AliasBindRequired
@worktrees/businesses/<featureId>the promise head and its lifecycle state, by content address from the registry; the one place this operator writes outside its branchyes
@workspaces/bethe routed backend checkout read at the frozen head; every fact claim cites it by path, line range, and headyes

Inputs

KindFromRequired
architecture-decisionarchitecture.decide; architecture evidence, never a source of business behaviourno
backend-source-applicationbackend.source.apply; the delivered source a reconciliation reads, required under mode reconcile and refused otherwiseno

Requirements

FieldTypeDefaultAsk
featureIdidThe one feature the promise belongs to
modechoicemodelmodel decides and publishes the promise; reconcile compares the published head against delivered source
promisepromptthe promise the previous head statesThe promise in the person’s words; required on a first run, when no head exists yet, and recorded as the intent claim bound to request/request.json#requirements.promise
targetStatechoicepending, in-progress, implemented or rejected for the published head
dimensionslistthe dimensions of the previous headThe coverage surface this promise is accountable for; required on a first run, because no previous head declares it
approvalidnullThe owner approval the transition needs, supplied on resume after APPROVAL_REQUIRED
resumetokennullThe blocked branch’s token when re-entering after a stop

Steps

#StepParamsReadsWritesStops with
1Validate the gate and resumeresume, moderequest/request.json, @workspaces/be at the frozen headINVALID_INPUT, SOURCE_DRIFT, NO_PROGRESS
2Normalize the evidence into claims@workspaces/be, every observation with its role, path, line range and head, input architecture-decision when present as evidence only, @tools/gitresponse/data/claims.jsonEVIDENCE_MISSING, CONTRADICTION_UNRESOLVED
3Check the published head and the transition authorityfeatureId, targetState, approval@worktrees/businesses/<featureId>: the current head, its state and its frozen evidenceLIFECYCLE_TRANSITION_INVALID, AUTHORITY_CONFLICT, APPROVAL_REQUIRED
4Model the promise, its actor and its eligibility, under mode model: fact claims carry every enforcing row, the intent claim carries the promise itselfpromiseresponse/data/claims.json, @workspaces/be at the frozen head, @tools/websearchEVIDENCE_MISSING
5Freeze the coverage matrix, under mode modeldimensionsresponse/data/claims.json, @workspaces/be and the surface it discoversresponse/data/coverage-matrix.jsonCOVERAGE_INCOMPLETE, CONSUMER_UNPROVEN
6Dispose legacy coexistence, under mode modelresponse/data/coverage-matrix.json: the legacy create, read and settle rows and their proofCONTRADICTION_UNRESOLVED
7Reconcile against delivered source, under mode reconcileinput backend-source-application, @workspaces/be at the frozen head, the coverage matrix frozen at the published headRECONCILIATION_DISCREPANCY
8Publish one head under an exclusive leaseresponse/data/claims.json, @worktrees/businesses/<featureId> at the previous head@worktrees/businesses/<featureId> as the new model.json head, response/data/model.json, @tools/sourcewriteSOURCE_DRIFT
9Emiteverything aboveresponse/response.md, response/response.json

Legacy create, read, and settle each take their own row when they are declared: a new sale path may retire legacy creation only while already-purchased rights stay readable and pending legacy settlement still completes, and the retirement carries proof that the creation path is closed. The matrix is content addressed and its fingerprint travels in the binding, so backend implementation, quality integration, and UAT can prove they consumed the same matrix rather than a paraphrase of it. A resume begins again at step 1, reuses only unchanged fingerprinted observations, and consumes the exact delta; republished evidence arrives as a new evidence fingerprint, because the same fingerprint cannot yield a different answer.

Outputs

KindFileTypeRequired
business-promise-authorityresponse/response.mdmdyes
claimsresponse/data/claims.jsondatayes
coverage-matrixresponse/data/coverage-matrix.jsondatano
modelresponse/data/model.jsondatayes

Stops

CodeDisposition
INVALID_INPUTterminate
SOURCE_DRIFTterminate
NO_PROGRESSterminate
EVIDENCE_MISSINGterminate
CONTRADICTION_UNRESOLVEDterminate
LIFECYCLE_TRANSITION_INVALIDterminate
AUTHORITY_CONFLICTterminate
APPROVAL_REQUIREDterminate
COVERAGE_INCOMPLETEterminate
CONSUMER_UNPROVENterminate
RECONCILIATION_DISCREPANCYterminate

Next

WhenOperator
the promise is published and a frontend surface must carry itfrontend.direction.decide
the promise is published and a backend contract must carry itbackend.source.apply
the promise needs boundaries and data ownership decided before it can be enforcedarchitecture.decide
the head is reconciled against the delivered source and the delivery may be publishedgit.publish

Source: operators/business-decide/operator.md.