picatz / picatz/flowstate

cel: Flowstate's own libraries declare no documentation — `json_parse`, `digest.sha256`, the duration units, `lists.range`, `sum` and `reduce` carry no `FunctionDocs`/`OverloadExamples`/`MacroDocs`, and the catalog discards the descriptions cel-go already ships for `size`, `has`, `map`, `optional.of` and `_?._`

Open
#1,850 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

documentation dsl enhancement
Dominant language
Go
Stars
9
Forks
0
Avg merge
3h 3m
Merged PRs (30d)
509

Description

Observed behavior

At 7530b29 against github.com/google/cel-go v0.31.0.

cel-go's declaration API carries documentation in code: cel.FunctionDocs(...) on a function, cel.OverloadExamples(...) on an overload, cel.MacroDocs(...)/cel.MacroExamples(...) on a macro, cel.VariableWithDoc(...) on a variable, all surfaced through one common.Documentor interface (common/doc.go: Doc{Kind, Name, Type, Signature, Description, Children}). It is present at the pinned version, not something a bump brings. cel-go's standard library and its optional library use it on every function; asked through the profile environment:

name Documentation().Description overload examples
size "compute the size of a list or map, the number of characters in a string, or the number of bytes in a sequence" 8
_+_ "adds two numeric values or concatenates two strings, bytes, or lists." 9
_?._ "if the field is present create an optional of the field value, otherwise return optional.none()" 1
optional.of "create a new optional_type(T) with a value where any value is considered valid" 1
has (macro) "check a protocol buffer message for the presence of a field, or check a map for the presence of a string key. …" 3
map (macro) "the three-argument form of map transforms all elements in the input range." 4
optMap (macro) "perform computation on the value if present and return the result as an optional" 2
json_parse "" 0
digest.sha256 "" 0
days "" 0
lists.range (the override in cellistbound.go:65) "" 0
sum, reduce (macros, celfold.go:131) "" 0

Every first-party declaration is bare: jsonLibrary (celenv.go:813), digestLibrary (celdigest.go:19), durationLibrary (celenv.go:876), listRangeLibrary (cellistbound.go:65) call cel.Function/cel.Overload with a binding and nothing else; foldLibrary calls cel.ReceiverMacro with no MacroOpt. The prose that explains each of them — why days(3) is exactly 72 hours, that digest.sha256 is a checksum and not a MAC, that sum folds with + and an empty list sums to int 0 — lives in Go doc comments an author never sees.

The catalog then discards what cel-go does carry. functionSignatures (catalog_functions.go:196) calls fn.Documentation() and reads only each overload's Signature; Description and the example children are dropped. LibraryFunction (catalog_functions.go:24) has Name, Library, Example, Macro, Signature and no description or examples field. env.Macros() is consulted for names only (declaredNames, catalog_functions.go:158); common.Documentor is never type-asserted on a macro, so has's and map's documentation is unreachable from any Flowstate surface. macroExamples (catalog_functions.go:276) is a hand table for every macro, including the two Flowstate owns.

One correction for the record, since the upstream reading was part of this pass: cel-expr/cel-go#1415 is the JWT library, not a documentation change. It is the newest example of the idiom — every function in ext/security/jwt declares cel.FunctionDocs and cel.OverloadExamples — but the API predates v0.31.0. cel-go's own ext/* libraries (strings, lists, math, sets, encoders, bindings, comprehensions, regex, protos) contain zero FunctionDocs/OverloadExamples call sites at v0.31.0 and at upstream master (aa72cde, 2026-09-04), so strings.quote, sets.contains, regex.extract, math.sqrt cannot be described by derivation today; that half is an upstream gap and is recorded in the contributions ledger (#1862) rather than here.

Why it matters

The catalog is the one source every surface reads (flow tasks, hover, completion, docs/reference/cel.md, the MCP CELFunction rows, flowtest), by design (#573, #702). A field the catalog does not carry cannot appear on any of them, so an author or an agent who finds reduce in a listing still has to guess what its four arguments mean, and digest.sha256's one security sentence ("not a signature, MAC, password hash") is stated only in docs/reference/cel.md's hand-written idioms, where a rewording is caught by a compile test but a silent omission is not.

Desired outcome

Every function and macro Flowstate declares documents itself in code, in the upstream idiom, and the catalog carries description and examples for every name whose declaration has them.

The upstream shape, from common/stdlib/standard.go and cel/library.go at v0.31.0:

cel.Function("digest.sha256",
    cel.FunctionDocs(
        `compute the SHA-256 content digest of a string's UTF-8 bytes or of a bytes value,`,
        `as 'sha256:<lower-case hex>'; a checksum for identity and idempotency, not a MAC or signature`),
    cel.Overload("digest_sha256_string", []*cel.Type{cel.StringType}, cel.StringType,
        cel.OverloadExamples(`digest.sha256('') // 'sha256:e3b0c442…b855'`),
        cel.UnaryBinding(...)))

cel.ReceiverMacro("sum", 0, expandSum,
    cel.MacroDocs(`fold a list with +; an empty list sums to 0`),
    cel.MacroExamples(`[1, 2, 3].sum() // 6`, `[1.5, 2.5].sum() // 4.0`, `['a', 'b'].sum() // 'ab'`))

Examples are expression // result strings; a multi-line example is built with common.MultilineDescription. Two mechanics to respect: OverloadExamples joins its arguments with newlines and re-splits on blank lines (decls.OverloadDecl.Examplescommon.ParseDescriptions), so an example must not contain a blank line; MacroExamples keeps one example per argument.

Acceptance criteria

  • jsonLibrary, digestLibrary, durationLibrary, listRangeLibrary and foldLibrary carry FunctionDocs/OverloadExamples or MacroDocs/MacroExamples; the doc strings say what the Go comments say today (the 292-year bound on a unit, the fixed-offset meaning of days, the map refusal for sum).
  • LibraryFunction gains Description string and Examples []string, filled from Documentation() for functions and from common.Documentor on macros; CELFunction in proto/flowstate/v1/catalog.proto:108 gains the same two fields, regenerated (invariant 1 and 9), so the MCP catalog carries them without a second table.
  • macroExamples entries for sum and reduce are derived from MacroExamples and the table keeps only the macros cel-go declares without docs; TestEveryMacroHasAnExample still fails on a macro with neither.
  • A test evaluates every example in the profile whose text has the expr // result shape and asserts both sides evaluate to equal values under Evaluator.EvalString (the TestEveryMacroExampleEvaluates pattern, generalized), so an example is executable documentation rather than prose.
  • A coverage test lists every callable name in 2026.1 without a description and fails unless the name is on an explicit allowlist of upstream-undocumented ext names; the allowlist shrinks with the cel-go bump (#1480) and cannot grow with a first-party name.
  • docs/reference/cel.md is regenerated; rendering the new fields on hover, completion, flow tasks and the reference page is #1851.

Constraints and dependencies

  • Documentation is not language surface: no runtime name is added, so this joins 2026.1 without a profile question.
  • Descriptions for cel-go's ext functions are not derivable until upstream carries them; an in-tree description table for those names would be the second source of truth #573 exists to avoid, so the allowlist above is the honest state until then.
  • #1506 (signature help), #1852 (the authoring prompt) and #1742 (llms.txt) consume what this produces; none is blocked on it. #1853 (packaging the same libraries as cel.SingletonLibrary values) touches the same declarations.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with jsonLibrary, digestLibrary, durationLibrary, listRangeLibrary, foldLibrary, functionSignatures, and macroExamples in the named Go files, comparing their declarations with cel-go v0.31.0's documentation APIs. Run the catalog, macro example, and coverage tests, then regenerate proto/flowstate/v1/catalog.proto and docs/reference/cel.md. Done means first-party descriptions and examples reach the catalog and only explicitly allowlisted upstream-undocumented ext names remain.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
documentation, tooling
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.