package ingest // vocabulary.go: the platform's INTERNAL words and the contract's, in one place. // // Here rather than beside the HTTP handlers, because everything that does NOT go through a handler // — every SSE frame — carried the internal word instead. // // The rule: a value crossing the boundary is translated HERE, and one this build cannot name travels // as the empty string, which every projection renders as `null`. // The reasons a RUN can be paused, in the platform's own vocabulary. Only the first has a contract // word; the other two are distinctions this side makes and the wire has no name for. const ( // PausedRunLimitReached — the run spent the ORDER it was sold: the platform's own ceiling, set // flush against the hold it took. // // ⛔ IT IS NOT `credit_exhausted`, AND THE SEPARATION IS PD-446. The two used to be one word, and // the word was the account's: measured on 04.09, a run stood `paused_reason: credit_exhausted` // while `GET /v0/usage` answered `state: ok, halt_reason: null` with $0.102494 of $0.30 left. // BOTH answers were right — the halt is read off the ACCOUNT and the account had money — and the // user read «your credit ran out» beside «34% remaining». What ended was the purchase, not the // credit, and the remedy differs: this one is bought again, `credit_exhausted` is topped up. PausedRunLimitReached = "run_limit_reached" // PausedCreditExhausted is the ACCOUNT's own halt — nothing left to spend at all. It stays the // account's word (ReadUsage) and is no longer produced for a run's own ceiling. PausedCreditExhausted = "credit_exhausted" PausedDailyCeiling = "daily_ceiling" // the engine's, out of a book.yaml the operator owns PausedCeilingUnknown = "ceiling_unknown" // read from the exit code alone; whose limit is unknown ) // The reasons an INTAKE can end, in the platform's own vocabulary. const ( // RejectSourceUnreadable — cut and no book in it. The ONE reason that deletes the user's source. RejectSourceUnreadable = "source_unreadable" RejectNotConfigured = "not_configured" // nothing to be parsed against RejectParserUnavailable = "parser_unavailable" // the engine could not be RUN, repeatedly RejectStorageUnavailable = "storage_unavailable" // the storage root is not there RejectSchemaMismatch = "schema_mismatch" // the project database is another build's schema ) // ContractPausedReason is the wire vocabulary of `PausedReason`, which enumerates TWO values since // the order form's minor: `run_limit_reached` and `credit_exhausted`. // // A reason the contract has no word for travels as nothing, which is exactly what the contract asks // a client to render: the neutral halted, continuable state. Inventing a wire value for a // distinction this side makes is not this zone's right (register row PD-199, ratified D39.132 п.2а). func ContractPausedReason(internal string) string { if internal == PausedCreditExhausted || internal == PausedRunLimitReached { return internal } return "" } // ContractHaltReason is the ACCOUNT's own vocabulary (`AccountHaltReason`), apart from the run's and // not a duplicate that shares a value today: lighting an account-wide halt from a reason that says // nothing about the account tells a user with money that they have none. func ContractHaltReason(internal string) string { if internal == PausedCreditExhausted { return "credit_exhausted" } return "" } // ContractRejectReason is the wire vocabulary of `RejectReason`. // // The two differ by one value and by intent: `parser_unavailable` names OUR component, and the name // of a value is what a client hangs a phrase on — so the contract calls the same fact // `processing_failed`, by its effect (companion ФБ-9). The other two internal reasons never end an // intake at all, so a book carrying one came from an older build or from a hand; they are mapped by // effect for the same reason, and anything unrecognised travels as nothing, which the contract // declares legal for a rejected book. func ContractRejectReason(internal string) string { switch internal { case RejectSourceUnreadable: return "source_unreadable" case RejectNotConfigured: return "not_configured" case RejectParserUnavailable, RejectStorageUnavailable, RejectSchemaMismatch: return "processing_failed" } return "" }