Repository navigation
feat(generate): runnables derives every method behind the hop, and every runnable is a tool - #1172
Merged
Merged
Conversation
…ery runnable is a tool `codefly generate runnables` now derives an operation for every served unary method that declares authority.hop.v1.policy, with nothing added to the proto (core feat/tools-from-endpoints). A read is written with recovery: RECOVERY_RECOMPUTE and no lookup; a mutation with RECOVERY_RECEIPT and the generic receipt lookup. Every operation.json carries the tool's presentation. A method a default derivation cannot turn into an operation (a stream, any_checked_caller, Any, recursion) is listed as "not an operation" and never fails the command; a marked method is refused exactly as before. operation.json gains `recovery` (omitted when unstated, so existing documents are byte-identical), carried through runnable-bindings into the prepared policy. Moves core to 45383f9f, which also needs ProtobufProcedures' new endpoint argument (core #836). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…scopes Moves core to 87497b44 (codefly-dev/core#843): a derived mutation is written with exactly the scopes its authority policy requires and no lookup scopes, its receipt read under those invoke scopes. The default-derivation test now holds both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… report of what became a tool (r87) r87 B1 — a derived release name over 50 characters is shortened deterministically to a stable prefix and an eight-digit digest of the whole name (core BoundedName), so a long method name never fails generation (module-document-store's GetDocumentTransformationReceipt and friends now derive). The refusal header no longer claims the methods carry the operation option: "N method(s) cannot be derived as runnable operations". r87 M2 / decision 6 — the run reports each operation's origin (option or default) and effect, the methods left plain calls and why, and, when any operation was derived by default, their count, the mutations among them, the grants rule and the codefly.runnable.v0.exclude opt-out. r87 m1 — the default-derivation test covers exclude carried as unknown option bytes (51004) and a release name past 50 characters. r87 B2 — moves core to 483255ec (core#843 with r86 fixed). The source-operation and document-store oracle tests follow the wire spelling (JSON names, int64 as strings): the producer's committed package is held to the derived one modulo that re-spelling until module-saas-starter regenerates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…no Go change) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ghter bridge (r102) r102 m1 — the summary counts and names methods, each once, and a notice prints once per method, though one method is an operation per endpoint. r102 m2 — the origin is core's OperationSpec.Declared; declaresOperation, a second mechanism for the same fact, is gone. r102 m3 — requireSameModuloWireSpelling requires format int64/uint64 on an INTEGER that became a STRING, every non-required key optional, and recurses into array items. r102 m4 — core at 0c02ef0f (core#843 with r100's majors fixed): every non-required key optional on the wire, so the document-store oracle pin moves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ence regenerated Re-pins core to v0.19.7-0.20261026023455-8b5ddef6d55a, #843 as merged. That commit also carries core#845 (WorkScopeV1.resource_owner_id) and core#835's module-contract kit fixture roles-grant-bindings. - docs/cli-reference.md: regenerated with `go test ./cmd -run TestCLIReferenceIsCurrent -update-reference` for this branch's new `generate runnables` help text. - The round-trip test exempts WorkScopeV1.resource_owner_id by name: core refuses an operation that declares an owner, so the document has nothing to carry. TestRunnablesRefusesADeclaredResourceOwner proves the refusal reaches `codefly generate runnables` with core's reason. - The module-contract kit's staging composition supplies the audiences roles-grant-bindings resolves (the same line as #1167, so the two merge cleanly). The document-store oracle digest is unchanged (4b72d393...). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # go.mod # go.sum # pkg/gitops/wire_kits_test.go
This was referenced Oct 26, 2026
Merged
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.
What we are trying to do
Make every endpoint RPC a runnable, and therefore a tool, with zero per-RPC work. The core half is in codefly-dev/core#843. This PR is the generator half:
codefly generate runnablesandrunnable-bindings.The change
generate runnablesderives an operation for every served unary method that declaresauthority.hop.v1.policy. No proto edits are needed."recovery": "RECOVERY_RECOMPUTE", emptylookup_scopesand no lookup.RECOVERY_RECEIPT, exactly the scopes its policy requires, no lookup scopes (its receipt is read under the invoke scopes by the caller that made the effect) andmax_attempts: 1.operation.jsoncarries the tool's presentation.Lookup<Op>, or another operation'slookup_method) are not derived.authority/behind-the-hopnow generates 110 operations. The refusal header no longer claims the methods carry the operation option.optionordefault) and effect. The methods left plain calls are listed with the reason. When anything was derived by default, the run gives the count, names the mutations, and states the grants rule and thecodefly.runnable.v0.excludeopt-out:any_checked_caller,Any, recursion) is listed asnot an operation: …and never fails the command.operation.jsongainsrecovery. It is omitted when unstated, andrunnable-bindingscarries it into the prepared policy.OperationSpec.Declared, not a second reading of the descriptor. The summary names each method once, even when it is published on several endpoints.composition.ProtobufProcedures(set, *endpoint)follows core generate proto: a template whose outputs sit beside --proto regenerates nothing (0.1.145 reports success) or is refused (0.1.160) #836's signature change.Tests
TestGenerateRunnablesDerivesEveryMethodBehindTheHopcarries the policy andexcludeas unknown option bytes, as on disk. It covers:[write]only with no lookup;go test ./cmd/generate/ ./pkg/runnables/ ./cmd/show/...passes.golangci-lint --new-from-rev=5536d731reports 0 issues.Proof (obin-ai/module-annotations PR #65 at 3a9fcd6, no proto edits)
runnable-bindingsprepared all 32.Regeneration (expected drift, r87 M1 / decision 7)
Every module's
--checkgate goes red on this bump, and that is intended:Regenerate per module and per composition environment:
A newly derived operation reaches a person only through grants. Add
option (codefly.runnable.v0.exclude) = true;on anything no agent may ever call.Follow-ups (not in this PR)
Receipts/Lookup. It must admit a lookup only for the recordedReceiptIdentity(owner and acting principal), holding the lookup scopes or else the invoke scopes, exactly as core'sAdmitReceiptLookupdecides.pkg/runnable.JSONSchemamust learnNUMBER,JSON,formatandvalues, and mint a lookup under the invoke scopes whenlookup_scopesis empty.Classification: fix at the owner (core plus the CLI generator). No hack.
🤖 Generated with Claude Code