Repository navigation
Conversation
The plugin pinned the fctl SDK to a personal fork (Dav-14/fctl-v2-poc @ 545521bf). Repin to the canonical formancehq/fctl-v2-poc at e9b1395f, the MVP5 integration tip. Both hashes were recomputed from that revision through the same projection the validator uses: `git archive` of the locked sdkPath and witPath, then `nix hash path --type sha256 --sri` over pkg/plugin and `shasum -a 256` over the canonical WIT. The WIT hash is unchanged, so the plugin's vendored contract still matches. The authoring toolchain is byte-identical across both revisions (rust 1.91.1, wasm-tools 1.239.0, componentize-go 0.4.1, wasi-virt 448f6df8, same wasi-virt patch), so only the provenance revision moves. `go mod tidy` promotes google.golang.org/protobuf to a direct requirement under the new SDK.
The catalogue declared Auth product major 1, which contradicts both authoritative sources: the Stack v3.2 service-info authority binds Auth to image v2.5.0 (product major 2), and this repository's own latest release tag is v2.5.0. No published Stack composition serves an Auth major 1. Because ValidateExecuteRequest checks the attested major against the declared compatibility set, the wrong declaration did not merely mislabel the surface: a host attesting major 1 was admitted and reached product traffic. Tests now pin the corrected major at both boundaries and prove major 1 is refused before any host request is emitted.
`just fctl-audit-lint` could not run while the SDK lock pointed at a fork revision unavailable to this checkout: the wrapper aborted at pin validation before golangci-lint started. Repinning makes the recipe reachable, which surfaces two pre-existing errcheck violations. Both writes are genuinely unrecoverable — a failed diagnostic write to stderr and a deferred close on a read-only file — so the returns are discarded explicitly rather than handled.
Seven of the nine Auth commands now declare an explicit, ordered RenderHints.Table for the human view. Columns are a compact subset of scalar properties the emitted public result really carries; nested containers, unbounded free text and display-once credential material are excluded. PublicOutputSchema is untouched, so --output json and --output yaml keep returning the complete public result. deleteClient and deleteSecret return 204 with no declared response schema and emit a canonical empty object, so auth clients delete and auth clients secrets delete are left without a hint rather than given an invented column. Coherence is not asserted from a hand-written list: the new catalogue tests execute each command against the widest documented fixture and read the property set back out of the adapter's own emitted envelope, with the fixtures pinned to the generated client's JSON tags.
The render-hint tests could pass without proving much, and two decisions
behind the column lists were inferred rather than recorded.
Header casing is now a recorded decision, not an inference. Both sources
that actually spell a header agree on Title Case: shipped fctl v3 prints
`ID Name Description Public Permissions` and `ID Subject Email` for the
two Auth list commands, and the fctl SDK's own RenderHints examples use
`{Header: "Display Name"}`, `{Header: "Name"}`, `{Header: "ID"}`. The
host's strings.ToUpper in renderTable is the no-layout fallback these
hints exist to replace and never touches an authored Header, so it is
not a counter-example. The declared headers are unchanged; the test now
derives the expected header from the field, so a new column cannot
introduce a different casing.
The compact-detail trade-off is now documented and asserted. Hinting
show/create/update means a host that honours the hints renders four
scalars instead of ten properties, and that is intended: the table is a
compact scalar summary, and every dropped field stays in the emitted
public result and in PublicOutputSchema. The new test fails if a column
resolves to a container, if the omitted set stops matching the recorded
decision, or if an omitted property leaves the public result.
Coherence no longer depends on the schemas being permissive. A Field is
backed when the emitted public result resolves it to a scalar or the
schema declares it, and a command with no public output schema is itself
a violation — erasing the schema on all nine commands now fails in core
rather than only in the component descriptor test. Path resolution is
generic and collection-transparent, matching the dotted Field paths in
the SDK's examples, and is proven directly rather than through a
catalogue that would not exercise it. The schema bytes of all nine
commands are pinned, so a narrowing fails here too.
Fixtures are pinned to every generated type they encode, adding
components.Secret and components.ClientSecret to the two already
covered; the ClientSecret fixture was missing `metadata`. The hintless
classification now reports the real condition instead of its inverse,
reports every offender instead of the first, and fails on a command
classified neither way. A want entry naming no catalogue command is no
longer skipped silently.
Verified without Nix through an equivalent go.work against the pinned
SDK: race suite, coverage gate at 87.3%, guest entrypoint, vet, gofmt.
Seven mutations confirm each guard bites.
Member
|
Closed automatically: bulk PR cleanup |
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.
Adds the portable Auth command/auth facets, exact SDK pinning, command catalogue, sensitive-output contracts, and stable RenderHints for CLI consumers.
Scope
Confined to
plugins/fctl/, plus the flake andJustfileentries that pin and reach the plugin's own toolchain. No change to the Auth service code.Validation
nix develop --command just pre-commitpasses locallyKnown issues
The
Dirtycheck fails: the pinned fctl SDK is unreachable from CIplugins/fctl/scripts/with-fctl-sdk.shresolves the pinned SDK throughFCTL_SDK_ROOT, which no workflow sets and which assumes a developercheckout. CI therefore reaches the plugin gate with nothing to point at:
formancehq/fctl-v2-pocis private and a repository-scoped CI token cannotclone it, so supplying a credential is not a viable fix. The established
remedy in this codebase is a committed SDK bundle, pinned by commit provenance
and verified by the same SDK and WIT content hashes — the approach already
green in
formancehq/connectivityandformancehq/ledger.Local runs pass only because they point
FCTL_SDK_ROOTat a checkout; thatgreen does not carry to CI.
FCTL_SDK_ROOTan override, so the plugin gate runs in CI without a credentialThis is the only remaining red check. The earlier crates.io HTTP 403 failure is
resolved: the Rust authoring toolchain no longer loads in the default dev
shell, so ordinary Go jobs no longer build it.