docs(api): discovery, naming, groups, events, rules, flows and DNS (C5) - #40
Merged
Merged
Conversation
Name the API daeuniverse/native and keep engine identity in engine.name. Engine-only routes, capability keys, links and fields live under x-<engine>; the capability resources and discovery links accept no other unlisted member. Each event kind lists what it invalidates, and every activation is followed by runtime.updated. The stale honk evidence page leaves the published docs; rule_source (now with userspace) and the outbound counters are defined inline, and the current honk notes get their own page.
The patch target is the group's policy and config as GET returns them; operations apply in order, remove drops the group's value so the engine's inheritance applies, null is accepted only where the schema allows it, copy and move validate like add, and the result is normalized and revalidated before commit. Keep one check_url and carry dae's check addresses in x-dae. Add dae's fixed policy and a nullable interrupt_connections. config_revision is configuration-wide and config_patch requires writable configuration.
DNS query sends traffic and writes the cache, so it becomes POST with a JSON body (RFC 9110). max_rules is never below the running list's size, so rules and DNS rules no longer answer a 503 that cannot succeed. Rule and DNS rule expressions share one display rule. FlowSummary gains rule_generation_id for the join with GET /rules.
interrupt_connections accepts null in a patch like the other nullable group options; an engine without the option leaves it out of mutable_config, so changing it returns 422 unsupported_value. Group config is closed except for x-<engine> members, which GET reports and PATCH does not address. fixed always uses its configured member, even when that member fails its check. Discovery extension links appear in the admitted view only, engine-only routes MUST sit under /api/v1/x-<engine>/, runtime.updated also invalidates capabilities, and DNS query documents its 404 for an unavailable capability.
Say what the JSON body keeps out of access logs and what it does not, how clients use the Invalidates column, when expression is source text, how flow rule generations join to GET /rules, and what the outbound counters count. The honk notes drop "current" and the repeated not-part-of-the-contract line.
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.
C5 of the API contract revision plan: discovery, naming, groups, events, rules, flows and DNS. Three commits: naming, extensions and events; groups; DNS, rules and flows. Two more address review (see Review fixes).
yarn check:contractpasses (84 tests, 3 new), andhexo generatepasses the link check.Honk status per finding: matches means honk already behaves as written; HC means honk changes in its HC PR (rows appended to the drift ledger).
F6 Event invalidation (Q5)
events.mdgains an Invalidates column. A server sendsruntime.updatedafter any change in its row, either coalesced or on a sampling tick, and every activation is followed byruntime.updatedonce its runtime-settings reset is visible. No per-resource events.observation.rscommittedpublishesruntime.updatedaftersettings.activateon every commit (control/reload/transaction.rs:765-772), and the sampler tick (server.rs:56) covers the rest. The conditional F6 item in HC is not needed.runtime.updatedfrom the reload completion path and a periodic tick; no new event kinds.F9 Engine extensions (Q6)
capabilities.md. Engine-only routes go under/api/v1/x-<engine>/, capability entries underresources["x-<engine>"], discovery links underlinks["x-<engine>"], and engine-only fields under anx-<engine>member.Capabilities.resourcesandAdmittedDiscovery.linksare now closed apart from^x-members, andengine.nameis a lowercase identifier (^[a-z][a-z0-9]*$). The/api/v1/discoveryalias is not allowed. A new test covers the namespaced and the rejected forms./api/v1/discoveryalias (handlers.rs:25,security.rs:259). Move config export, import, revisions, revision activation and/runtime/modeunder/api/v1/x-honk/, move their capability keys and links intox-honk, and movestoreinGET /configtox-honk.store(config/http.rs:80). Until HC lands, honk's capabilities and discovery fail the closed schemas.activate_direct/activate_proxystrings come fromcontrol/connection/udp.rsand its tests. Renaming them to anx-honk-form would touchcontrol/, which is not cheap, so I left them as engine-defined values documented in the honk notes.x-dae.F19 Group check URL and policies (Q9)
check_url(no list). dae's addresses after the URL go inconfig["x-dae"].check_addressesand are dropped when a patch changescheck_url.policy.kindgainsfixed, andinterrupt_connectionsbecomes nullable.fixed.tcp_check_url[0]maps tocheck_urlandtcp_check_url[1:]tox-dae.check_addresses(component/outbound/dialer/connectivity_check.go:426-445). Thefixedpolicy iscommon/consts/dialer.go:28. dae has no interrupt option, so it reportsnull.F20 Group JSON Patch semantics (Q10)
groups.md. The RFC 6902 target is{policy, config}as GET returns them, and operations apply in order and atomically.removemakes a member absent, so the engine's inheritance and defaults apply (in dae this includes the global group options).nullis allowed only where the schema allows it.copyandmoveare validated likeadd. A failedtestreturns 409;replace,removeorteston an absent member, orcopy/movefrom one, returns 400. The result is normalized and revalidated before commit.groups.rs:177-330:values[path].take(), 400invalid()on an absent member, 409 on a failedtest, and the post-loop tolerance check).F21 API name (Q11)
name/api.nameisdaeuniverse/native. It names the API, not the engine; engine identity is onlyengine.name. The masked-secret description now names the listener secret generically.types.rs:364,377,413).F23 Stale evidence page
docs/honk-mapping.mdis split. The current honk sections becomedocs/honk-notes.md, a non-normative page linked from the sidebar and the existing notes links. The pinned-revision evidence moves out of the published docs todesign/honk-evidence-780c3f1.md.rule_sourceand the outbound counters are defined inline, and every normative citation of the evidence page is removed (flows.yaml,flows.md,runtime-status.md,runtime.yaml,configuration.md,index.md).F27
max_rulesbelow the loaded countrules.max_rulesanddns_rules.max_rulesare never below the running list's size. An engine with a fixed bound either refuses the configuration at validation or advertises the larger size. The unreachable 503temporarily_unavailablepath and its examples are removed; 503snapshot_unavailablestays.routing.rs:27,50,378anddns/rules.rs:22,26,88advertise a fixed 4096 and return 503; they should reportmax(4096, count).F29 DNS query method (Q14)
POST /api/v1/dns/querywith a JSONDnsQueryRequestbody (domain,type[],upstream,cache_mode).detailstays a query parameter, a non-JSON body returns 415, and the rationale is RFC 9110 (the query sends traffic and writes the cache). The tests that used this operation for query-parameter tooling now useDELETE /dns/cache, and a new assertion checks that the queried name stays out of the request line.handlers.rs:542route,dns.rshandler).F32 Group revision scope
config_revisionis configuration-wide (the same asGET /configrevision), so an unrelated accepted change causes 412.groups.config_patchrequiresconfig.writable, and without it PATCH returns 404.catalog.rs:669,groups.rs:342, where the capabilityconfig_patchequalsconfig.editable()).F40 One expression rule
rules.md, linked from DNS rules.expressionis the source text as written when the engine has it, and otherwise the engine's rendering, with listener secrets masked.routing::located(routing.rs:141-153,255-262,dns/rules.rs:143-169).String()rendering.F41 Rule join key
FlowSummary.rule_generation_id(required, nullable). Join toGET /rulesonly when it equalsgeneration_id. A new test ties it to the route step that carries the samerule_id.flows.rssummary; the value is the generation of the traffic-route step).F46
rule_source: userspaceuserspace, the rule a userspace router decided with; each value is defined inline.userspace).userspacefor decisions made incontrol/dial.go:115-143.Review fixes
InterruptPatch.valueacceptsnull, which clears the group's own value like the other nullable options. For a supported option,nullmeans the group sets no value;interrupt_connections: nullcan also mean the engine has no such option. That engine leaves it out ofmutable_config, so changing it returns422 unsupported_valueunder the existing rule for fields the capabilities do not advertise. dae reportsnulland rejects a change.resources: known keys plus^x-[a-z][a-z0-9]*$objects.x-<engine>members, such asconfig["x-dae"].check_addresses, are reported by GET and are not patch targets. Tests cover an unnamespaced key and a non-object member.fixedis defined on its own: the group always uses its configured member, even when that member fails its check. dae'sfixed(index)maps to it (component/outbound/dialer_group.go:382-390ignores exclusion).check_intervaldrops the stale "see its mapping notes" clause.links["x-<engine>"]is in the admitted discovery view only; the public view's links stay closed.runtime.updatedalso invalidates capabilities, because a recorder mode change movesresources.flows.recordingwithout a new generation.POST /dns/querykeeps its404: it is thecapability_not_supportedcase whenresources.dns_queryis unavailable, now documented./api/v1/x-<engine>/.dns-query.md,events.md,groups.md,rules.md,dns-rules.md,flows.yaml,runtime.yamland the honk notes.tolerance50 andinterrupt_connectionsfalse) and for the traffic fallbackexpression(honk returns the literalfallback; DNS fallback already rendersfallback: <outbound>). F40 is otherwise unchanged. The F9 migration also moves the nested capabilityconfig.store.