Repository navigation
feat: lookup(query), credential_for, dns_chain, secret_describe (WI-848, WI-864) - #50
Merged
Merged
Conversation
Agents could not ask Cadastre the questions they actually had, so they bypassed it: 27/27 logged `lookup` failures were a phrase passed where an exact entity_id was required; the Infisical project id an API call needs was not discoverable; and prod deploy #49 failed on a secret with raw newlines that only a hand-written, value-reading script could find. - lookup takes `entity_id` or `query`; a query ranks declared and observed entities and secrets (CLI `search`, HTTP /search). Secret hits carry store, project id/slug, environment, path, server and a ready agent-auth manifest line (WI-848). - credential_for(service, action): ranked secrets from name matches and declared consumes_secret, retired names last (WI-848). - dns_chain(hostname): record -> ingress edge -> node -> service from collected evidence; flags a proxied hostname pointing at a workload node instead of the edge (the 2026-08-26 outage, pinned by a fixture test). Catalog-only, never resolves live (WI-848). - secret_describe(ref): location, version, timestamps, consumers and value shape (length, newline/CR counts, JSON parse) - never the value. The secrets-infisical collector computes the shape in its own process from the value its list call already returns (x-secret-store); the value never reaches the query layer. orchestrator-gitops records interpolated variable names so consumers can be named (WI-864). - MCP schemas describe every argument; malformed calls get required and accepted arguments, a did-you-mean and an example. Streamable HTTP now enforces context_for's `intent` as required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Why
Agents bypassed Cadastre because it could not answer the questions they had:
lookuperrors were callers passingquery(a phrase) where the requiredentity_idwas expected.context_for/checkrequired fields were unclear from the schema.lookupreturnedinfisical://apps/prod/NAMEonly.What
WI-848
lookup(entity_id | query, kind, limit):queryranks declared + observed entities and secrets by token overlap (declared and observed secrets merged by ref). Secret hits carrystore,project_id,project_slug,environment,path,serverand a ready agent-auth manifest line (VAR PROJECT_ID SECRET_NAME). CLIcadastre search, HTTPGET /search.credential_for(service, action): ranked secrets from name matches + declaredconsumes_secret, action hints (deploy/ssh/push/...), revoked/retired names ranked last, plus the service's endpoints. CLIcredential-for, HTTPGET /credential-for.dns_chain(hostname): A/AAAA/CNAME (+ covering wildcard) → address owner (endpoint addresses, hostx-*.addressese.g.x-tailscale) → expected ingress (fronted_by) → node → service. Findings:points_at_workload,wrong_ingress,points_elsewhere,upstream_mismatch,unknown_address,no_record,declared_observed_differ. Catalog-only (no live resolution; LAN split-horizon stated as a limitation). The 08-26 misconfiguration is a fixture test.context_for(query=…)→intent) and an example. Streamable HTTP now actually enforcescontext_for'sintent(it usedrequired_arguments or (), so a missing intent slipped through).WI-864
secret_describe(ref)(ref, id, or bare key): project slug + id, env, path, server, version,updated_at/created_at, last rotated, consumers (declaredconsumes_secret+ observed stacks interpolating the name), and value shape: length, bytes, lines, newline/CR/tab/control counts, whitespace flags, parses-as-JSON + JSON type, plus plain-language problems. CLIsecret-describe, HTTPGET /secret-describe.secrets-infisicalcollector already receives values from/api/v3/secrets/rawand drops them; it now reduces each value tocore.secretshapecounts in the same step and emits anx-secret-storeblock (declared in the plugin's attribute schema). This keeps DESIGN §8 ("secret values never transit the query layer") and needs no Infisical credential in the API/MCP containers (which don't hold one). Trade-off: shape freshness = lastcollect. No hash is stored (offline-guessing oracle).orchestrator-gitopsrecords interpolated variable names (${NAME},$NAME,[[NAME]]) asx-orchestrator.variable_refs— names only.Tests
tests/test_search_and_describe.py(23): shape function; collector emits shape/location with no value;komodo api key→ manifest line without entity_id; declared/observed merge; config fallback for project id; lookup query/entity_id dispatch + error; did-you-mean/required/example errors; schema descriptions; credential ranking (pair first, revoked last); declared consumption; deploy-build(deps): Bump the ui-minor group across 1 directory with 8 updates #49 shape; consumers; full-ref JSON; Streamable HTTP + HTTP routes end to end. Every answer is rendered (JSON + text) and checked that no 5-char fragment of any fake secret value appears.tests/test_dns_chain.py(10): the 2026-08-26 misconfiguration, VPN-evidence variant, correct chain, CNAME, wildcard, no record, unknown address, declared≠observed, limitations, normalization./searchis named HTTP-only since MCP serves it aslookup(query=…));ui/src/api/generated.tsregenerated.Gates run locally:
ruff check,ruff format --check,mypy,pytest -q(all pass),cadastre fmt --check,cadastre check compose.production.yaml --kind compose.Deploy note
Not deployed. Live
project_id/shape/consumers appear after the nextcadastre collectwith this version; until then secret hits fall back to the source'sworkspace_idwhenplugins.yamlis visible to the serving process, else report the project id as unknown.🤖 Generated with Claude Code