Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
138 commits
Select commit Hold shift + click to select a range
eb69661
fix(accounts): register installation REST handlers
lukazhupa Oct 20, 2026
5e556f3
style(accounts): apply canonical test import grouping
lukazhupa Oct 20, 2026
3a725d6
fix(accounts): fence invocation against the admitted source declaration
lukazhupa Oct 20, 2026
9d712fc
fix(accounts): export the optional declaration fence to consumers
lukazhupa Oct 20, 2026
07cd891
feat(accounts): serve the published host interfaces as adapters; the …
antoinetoussaint-byte Oct 22, 2026
0d6e682
feat(accounts): the host interfaces under host-owned names
antoinetoussaint-byte Oct 22, 2026
6a55fca
fix(accounts): the last consumer names in comments and the module dec…
antoinetoussaint-byte Oct 22, 2026
2d701da
fix(accounts): regenerate the authorization matrix under the host-own…
antoinetoussaint-byte Oct 22, 2026
4956638
docs(accounts): gap 7 closed in the host interface note
antoinetoussaint-byte Oct 22, 2026
c74ee5c
feat(accounts): the catalog carries the implemented interface package…
antoinetoussaint-byte Oct 22, 2026
981c673
fix(accounts): ApplyManifest declares no audit event; the delivery pa…
antoinetoussaint-byte Oct 22, 2026
bcd1afe
feat(accounts): the person shape is the caller's own session; protos …
antoinetoussaint-byte Oct 22, 2026
7eb5411
docs(accounts): the harness, step by step, from the integration tests…
antoinetoussaint-byte Oct 22, 2026
82235b2
test(accounts): the rung 1 harness — the interface conformance suite …
antoinetoussaint-byte Oct 22, 2026
3117e12
feat(accounts): the person line of the host interface suite is green;…
antoinetoussaint-byte Oct 22, 2026
f171fa8
test(accounts): the counted tripwires move for a public Check
antoinetoussaint-byte Oct 22, 2026
d8767c8
feat(accounts): a workload is issued behind the interface from its cr…
antoinetoussaint-byte Oct 22, 2026
27b1e95
feat(accounts): a child hop behind the interface, by the parent token…
antoinetoussaint-byte Oct 22, 2026
5b2d591
merge main into the authority interface branch
lukazhupa Oct 22, 2026
dfb7969
copy the composition interface's signed-carrier messages into the host
lukazhupa Oct 22, 2026
de43d6d
feat(accounts): a person's parent names its module's operation bindings
lukazhupa Oct 22, 2026
8d83e9d
chore(saas-sdk): regenerate the library from the accounts/connect con…
lukazhupa Oct 22, 2026
c14356e
Merge pull request #1220 from codefly-dev/authority-interface-one-hop
antoinetoussaint-byte Oct 23, 2026
6a172d7
chore(accounts): the interface protos at fdb7ea6 and the suite that s…
antoinetoussaint-byte Oct 23, 2026
7aee533
test(accounts): run the interface suite at 13 lines, the hop rule and…
antoinetoussaint-byte Oct 23, 2026
3818944
fix: bind authority child issuance to its authenticated actor
antoinetoussaint-byte Oct 25, 2026
2cce90c
feat(accounts): expose read-only fixture identity discovery
antoinetoussaint-byte Oct 25, 2026
daadf1b
merge main into the authority interface branch
antoinetoussaint-byte Oct 25, 2026
fb788f9
feat(accounts): serve what the authority's edge and hop call
antoinetoussaint-byte Oct 25, 2026
ea015f0
feat(accounts): a composing workspace's fixture grants, and List nami…
antoinetoussaint-byte Oct 25, 2026
59f667e
fix(accounts): admit declared hosts at a meshed cell's egress address…
antoinetoussaint-byte Oct 25, 2026
2aa0f6a
fix(accounts): the fixture-grants document is YAML, as Codefly reads …
antoinetoussaint-byte Oct 25, 2026
17fa593
fix(accounts): a workload's issue through a binding is addressed to t…
antoinetoussaint-byte Oct 25, 2026
6dbb2dd
fix(accounts): admit the environment's generated egress hosts, inert …
antoinetoussaint-byte Oct 25, 2026
7781263
fix(accounts): the composed-installation stand-in is a test package; …
antoinetoussaint-byte Oct 25, 2026
5270ac4
fix(accounts): an unwitnessed envelope narrowing is refused by name, …
antoinetoussaint-byte Oct 25, 2026
a77fb36
fix(accounts): a child issue through the actor's binding is addressed…
antoinetoussaint-byte Oct 25, 2026
e0a31d9
feat(accounts): a module's hop through its binding inherits its owner…
antoinetoussaint-byte Oct 25, 2026
f09507b
fix(accounts): an envelope entry that only gains is a grant, by the i…
antoinetoussaint-byte Oct 25, 2026
c6ebfd7
feat(accounts): a fixture declares its installations, performed by na…
antoinetoussaint-byte Oct 25, 2026
305cec0
fix(accounts): one sealed binding spelling and one module hop rule, a…
antoinetoussaint-byte Oct 25, 2026
3cc6438
fix(accounts): persist and enforce signed method-policy delivery
antoinetoussaint-byte Oct 25, 2026
461736d
fix(accounts): enforce delivered solution HTTP route policies
antoinetoussaint-byte Oct 25, 2026
0bd2b4f
fix(accounts): an installation's issue verifies the installation it n…
antoinetoussaint-byte Oct 25, 2026
14a077d
fix(accounts): a solution's delivered roles decide what a person hold…
antoinetoussaint-byte Oct 25, 2026
5e3ff10
Merge installation REST registration from PR #1185
antoinetoussaint-byte Oct 25, 2026
b437e29
fix(contracts): export the complete host interface with its owning CLI
antoinetoussaint-byte Oct 25, 2026
2eef6d6
fix(accounts): ListResources answers which resources a capability covers
antoinetoussaint-byte Oct 25, 2026
ed57089
fix(accounts): a solution's standing role is granted at its authority…
antoinetoussaint-byte Oct 25, 2026
ee1885e
docs(accounts): solution roles, ListResources and installation issuance
antoinetoussaint-byte Oct 25, 2026
e762949
Merge source declaration fencing from PR #1188
antoinetoussaint-byte Oct 25, 2026
b3f68aa
Merge person operation bindings from PR #1219
antoinetoussaint-byte Oct 25, 2026
c83e2c9
fix(accounts): pass person bindings through the host authority adapter
antoinetoussaint-byte Oct 25, 2026
9cba8c0
Merge concurrent authority interface updates
antoinetoussaint-byte Oct 25, 2026
92ec92b
fix(accounts): a team is exposed with the solution's own role
antoinetoussaint-byte Oct 25, 2026
6cd272f
Merge concurrent solution exposure fix
antoinetoussaint-byte Oct 25, 2026
14ff255
fix(accounts): one exposure rule, and its refusal names why
antoinetoussaint-byte Oct 25, 2026
eeda251
fix(accounts): declare host audit and documentation ownership
antoinetoussaint-byte Oct 25, 2026
c8c8fba
fix(accounts): derive fresh-store authority from signed manifests
antoinetoussaint-byte Oct 25, 2026
1e14641
fix(accounts): isolate composition delivery outcomes by binding
antoinetoussaint-byte Oct 25, 2026
ce64079
fix(ci): track registry publication and format accounts imports
antoinetoussaint-byte Oct 25, 2026
cd1f31b
fix(accounts): the authority interface holds each issue and check to …
antoinetoussaint-byte Oct 25, 2026
37aa3d2
fix(accounts): verify an applied authority document once, list resour…
antoinetoussaint-byte Oct 25, 2026
852ba3e
docs(accounts): the host interface after review r12
antoinetoussaint-byte Oct 25, 2026
da8e9ec
fix(accounts): admit resource-limited method scopes unchanged
antoinetoussaint-byte Oct 25, 2026
8bfa9ee
fix(accounts): project person holdings at each binding target
antoinetoussaint-byte Oct 25, 2026
c59a372
fix(accounts): refuse envelope authority absent from manifests
antoinetoussaint-byte Oct 25, 2026
fc40620
test(accounts): give the conformance harness every fixture the shared…
antoinetoussaint-byte Oct 25, 2026
e0adf4b
docs(accounts): the conformance harness supplies every fixture the su…
antoinetoussaint-byte Oct 25, 2026
913f397
fix(accounts): hold delivered solution roles to the manifest ceiling
antoinetoussaint-byte Oct 25, 2026
224264c
fix(accounts): the module tier proves the calling module, never a sha…
antoinetoussaint-byte Oct 25, 2026
9cf6064
fix(source-read-sdk): regenerate with codefly generate client; delete…
antoinetoussaint-byte Oct 25, 2026
c87472c
fix(frontend): regenerate collision-free TypeScript SDK exports
antoinetoussaint-byte Oct 25, 2026
2a6a3aa
fix(contracts): export MintSourceOperationContext on the accounts aut…
antoinetoussaint-byte Oct 25, 2026
6ace794
chore(accounts): the host interface protos at authority 0.2.0
antoinetoussaint-byte Oct 25, 2026
b2552f9
fix(accounts): the host interface behaviour the shared suite reaches
antoinetoussaint-byte Oct 25, 2026
137b210
style(accounts): goimports the host interface tests
antoinetoussaint-byte Oct 25, 2026
cf99a53
fix(accounts): a person's ask meets their holdings; a dropped kind st…
antoinetoussaint-byte Oct 26, 2026
52af9b0
chore(ci): pin codefly CLI 0.1.213
antoinetoussaint-byte Oct 26, 2026
04ffff6
test(accounts): the staleness probe exposes a real team with no member
antoinetoussaint-byte Oct 26, 2026
11897ef
docs(accounts): the host interface suite at 40 of 45, and what remains
antoinetoussaint-byte Oct 26, 2026
9b1a724
fix(accounts): the Work Context read oracles prove the calling module…
antoinetoussaint-byte Oct 26, 2026
c83fa89
test(auth-gateway): the admission fake records under a lock
antoinetoussaint-byte Oct 26, 2026
ce5eb55
fix(accounts): a mirror fetch joins its size watchdog and reads its b…
antoinetoussaint-byte Oct 26, 2026
2d7a98d
fix(accounts): an installation's agent stands in its organisation whi…
antoinetoussaint-byte Oct 26, 2026
45482b9
feat(accounts): an installation acting for itself owns its capability…
antoinetoussaint-byte Oct 26, 2026
463a341
test(accounts): the installation the suite refuses elsewhere is unrel…
antoinetoussaint-byte Oct 26, 2026
12c1699
docs(accounts): an installation owns its capability as its agent; the…
antoinetoussaint-byte Oct 26, 2026
3e06529
fix(accounts): resolve a module principal by its name; the binding is…
antoinetoussaint-byte Oct 26, 2026
0a9bde8
fix(accounts): a hop names its actor by the module's name
antoinetoussaint-byte Oct 26, 2026
cc050c6
test(accounts): an installation-owned hop names its actor by the modu…
antoinetoussaint-byte Oct 26, 2026
42bd286
docs(accounts): a hop's actor is the module's name; the suite at 43 o…
antoinetoussaint-byte Oct 26, 2026
217b9f1
feat(accounts): module delegations, revoked once and sealed to the gr…
antoinetoussaint-byte Oct 26, 2026
0537c46
feat(accounts): Delegate, GetDelegation, RevokeDelegation and Issue f…
antoinetoussaint-byte Oct 26, 2026
f19bfd3
test(accounts): a delegation is bounded by its grantor and ends with …
antoinetoussaint-byte Oct 26, 2026
732907c
docs(accounts): delegations behind the host interface, and what still…
antoinetoussaint-byte Oct 26, 2026
f571d0b
test(accounts): the hop fixture answers no module delegation; the del…
antoinetoussaint-byte Oct 26, 2026
fdd7f34
docs(accounts): the suite at 41 of 45 with delegations and the agent-…
antoinetoussaint-byte Oct 26, 2026
23b9579
docs(accounts): the suite at 45 of 45 with delegations
antoinetoussaint-byte Oct 26, 2026
e9b864f
Merge remote-tracking branch 'origin/main' into authority-interface
antoinetoussaint-byte Oct 26, 2026
178b854
fix(store): renumber this branch's migrations above main's 48
antoinetoussaint-byte Oct 26, 2026
4c24d95
fix(accounts): every hop of a chain is held to the binding it went th…
antoinetoussaint-byte Oct 26, 2026
682dae4
fix(accounts): a pinned principal is never issued outside its pin
antoinetoussaint-byte Oct 26, 2026
711e68c
fix(accounts): with no envelope, grant from the verified manifest byt…
antoinetoussaint-byte Oct 26, 2026
464b50e
docs(accounts): review r93 repairs; resolve the committed merge markers
antoinetoussaint-byte Oct 26, 2026
cbfc685
fix(accounts)!: the viewer oracles authenticate the calling module, t…
antoinetoussaint-byte Oct 26, 2026
3647298
fix(accounts): the module authority endpoint denies by default
antoinetoussaint-byte Oct 26, 2026
a99bec7
Merge remote-tracking branch 'origin/authority-interface' into author…
antoinetoussaint-byte Oct 26, 2026
7f4a28e
feat(audit): a delegation to a module is granted and revoked on its o…
antoinetoussaint-byte Oct 26, 2026
ddf7931
fix(accounts): a delegation fails closed, is the person's own, and en…
antoinetoussaint-byte Oct 26, 2026
32f09b9
test(accounts): delegations refuse borrowed credentials, fail closed,…
antoinetoussaint-byte Oct 26, 2026
60777a5
docs(accounts): delegations as served after r93; remove the committed…
antoinetoussaint-byte Oct 26, 2026
afe310f
test(accounts): the retained-binding integration asks as the module t…
antoinetoussaint-byte Oct 26, 2026
44786b2
feat(accounts): the journal records the binding and scope set a hop w…
antoinetoussaint-byte Oct 26, 2026
bc792b2
fix(accounts): hold each hop to the scope set it was issued under
antoinetoussaint-byte Oct 26, 2026
c8ad60f
docs(accounts): a hop is held to the scope set it was issued under
antoinetoussaint-byte Oct 26, 2026
3936c6a
fix(accounts): a module context the host does not admit is Unauthenti…
antoinetoussaint-byte Oct 26, 2026
29655de
Merge remote-tracking branch 'origin/authority-interface' into author…
antoinetoussaint-byte Oct 26, 2026
d807695
fix(store): renumber the actor-chain hop binding migration above this…
antoinetoussaint-byte Oct 26, 2026
5661374
chore(ci): pin codefly 0.1.214; regenerate both generated libraries w…
antoinetoussaint-byte Oct 26, 2026
8baa785
fix(accounts): with no envelope, a manifest widening waits for each o…
antoinetoussaint-byte Oct 26, 2026
0e29449
fix(accounts): the gateway never routes ApplyManifest; module deliver…
antoinetoussaint-byte Oct 26, 2026
1299246
fix(accounts): a following installation holds nothing on a host with …
antoinetoussaint-byte Oct 26, 2026
cc5d1f9
fix(accounts): one journal row per delegated issue; oracles confined …
antoinetoussaint-byte Oct 26, 2026
8b9e5ac
fix(accounts): credential refusals name their reason; Delegate needs …
antoinetoussaint-byte Oct 26, 2026
89a82d4
test(accounts): the shared suite runs ungated at authority main; dele…
antoinetoussaint-byte Oct 26, 2026
cde1d91
fix(store): the migration runner records and checks migration names
antoinetoussaint-byte Oct 26, 2026
da8a14f
docs(accounts): review r136 repairs
antoinetoussaint-byte Oct 26, 2026
32dd478
Merge remote-tracking branch 'origin/authority-interface' into author…
antoinetoussaint-byte Oct 26, 2026
8be4651
fix(accounts): record explicit module re-consent and close r153
antoinetoussaint-byte Oct 26, 2026
455602c
chore(contracts): regenerate runnables with CLI v0.1.215
antoinetoussaint-byte Oct 26, 2026
1084c36
fix(accounts): bind installation consent to reviewed authority
antoinetoussaint-byte Oct 26, 2026
3f2abbb
test(accounts): pass the consent-bound installation lifecycle conform…
antoinetoussaint-byte Oct 26, 2026
6dcd1f0
chore(contracts): regenerate exported contracts for the installation …
antoinetoussaint-byte Oct 26, 2026
2250f0f
test(frontend): install requests carry the reviewed consent approval
antoinetoussaint-byte Oct 26, 2026
51b3362
fix(accounts): admit directory reads with owner Work Contexts
antoinetoussaint-byte Oct 26, 2026
fce8e7e
fix(authority): preserve consent revisions and original hop grants
antoinetoussaint-byte Oct 26, 2026
61100e0
Merge remote authority-interface DirectoryService admission changes
antoinetoussaint-byte Oct 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,8 @@ jobs:
run: codefly generate contracts saas-starter --check
- name: Check derived source operations
run: codefly generate runnables saas-starter --check
- name: Check generated libraries are reproducible with the pinned CLI
run: bash scripts/ci/check-generated-libraries.sh

module-package:
name: Immutable module package
Expand Down
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ Skills in `.claude/skills/`, loaded when the task calls for them:

## Building, testing, and CI

- CI and local runtime qualification use released Codefly CLI **v0.1.215**,
pinned in `scripts/ci/install-codefly.sh`. It resolves the Codefly-owned
`egress` dependency and exports the multi-package host-interface contract.
- Canonical **service** gate: `codefly ci run`. It owns lint, compile/typecheck,
tests, dependency/vuln audit, SBOM, and container build for every service in
the graph. See [RELEASE_GATES.md](./RELEASE_GATES.md).
Expand Down
24 changes: 19 additions & 5 deletions configuration_defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,22 @@ func moduleDefaultFiles(group string) []string {
names = append(names, name)
}
}
// A document group (read with WorkspaceConfigurationDocument) is one YAML
// document, <group>.yaml, which is how Codefly reads a configuration
// document; its default is a document that states at least one key.
name := group + ".yaml"
if data, err := os.ReadFile(filepath.Join(moduleConfigLocalDir, name)); err == nil && statesADocument(data) {
names = append(names, name)
}
return names
}

// statesADocument reports whether data is one YAML mapping with at least one key.
func statesADocument(data []byte) bool {
var document map[string]any
return yaml.Unmarshal(data, &document) == nil && len(document) > 0
}

// repoRootMirrorsModule verifies the repo-root entry for name is a symlink that
// resolves to the module default of the same name. shipsDefault(workspace, …)
// alone is too weak: os.ReadFile follows the link, so it also passes a symlink
Expand Down Expand Up @@ -234,11 +247,12 @@ func assertSecretDefaultIsPlaceholder(t *testing.T, name string) {

func TestEveryDeclaredGroupShipsALocalDefault(t *testing.T) {
for _, group := range declaredWorkspaceConfigGroups(t) {
// CLI supplies this group per native run. An authored path (even an
// empty placeholder) conflicts with its render-owned declaration.
if group == "artifact-cache" {
// The CLI supplies these groups: artifact-cache per native run, egress
// from the environment's egress declaration. An authored path (even an
// empty placeholder) conflicts with its CLI-owned declaration.
if group == "artifact-cache" || group == "egress" {
for _, directory := range []string{moduleConfigLocalDir, workspaceConfigLocalDir} {
for _, suffix := range []string{".env", ".secret.env"} {
for _, suffix := range []string{".env", ".secret.env", ".yaml"} {
path := filepath.Join(directory, group+suffix)
if _, err := os.Lstat(path); !os.IsNotExist(err) {
t.Errorf("CLI-owned group %s must have no authored default at %s", group, path)
Expand All @@ -250,7 +264,7 @@ func TestEveryDeclaredGroupShipsALocalDefault(t *testing.T) {
// The base-synced location is what a base-synced consumer inherits.
moduleDefaults := moduleDefaultFiles(group)
if len(moduleDefaults) == 0 {
t.Errorf("declared config group %q has no default under the base-synced module subtree: add a %s/%s.env (or .secret.env) that assigns at least one variable, so a base-synced solution inherits it instead of dying at runtime-init with \"no configuration found for %s\"",
t.Errorf("declared config group %q has no default under the base-synced module subtree: add a %s/%s.env (or .secret.env, or a .yaml document) that assigns at least one variable, so a base-synced solution inherits it instead of dying at runtime-init with \"no configuration found for %s\"",
group, moduleConfigLocalDir, group, group)
}
// Each module default this group ships must be mirrored by a repo-root
Expand Down
1 change: 1 addition & 0 deletions configurations/local/fixture-grants.yaml
32 changes: 16 additions & 16 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module github.com/codefly-dev/agents/modules/saas-starter

go 1.27.0
go 1.27.3

require (
github.com/codefly-dev/core v0.18.0
github.com/codefly-dev/core v0.19.7-0.20261025161440-4e7f8ef01ed2
gopkg.in/yaml.v3 v3.0.1
)

Expand All @@ -16,20 +16,20 @@ require (
github.com/Masterminds/semver/v3 v3.5.0 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/go-openapi/analysis v1.0.0 // indirect
github.com/go-openapi/errors v0.22.8 // indirect
github.com/go-openapi/errors v0.22.9 // indirect
github.com/go-openapi/jsonpointer v1.0.1 // indirect
github.com/go-openapi/jsonreference v1.0.2 // indirect
github.com/go-openapi/loads v0.25.3 // indirect
github.com/go-openapi/spec v1.0.1 // indirect
github.com/go-openapi/strfmt v0.27.2 // indirect
github.com/go-openapi/swag/conv v0.29.1 // indirect
github.com/go-openapi/swag/jsonutils v0.29.1 // indirect
github.com/go-openapi/swag/loading v0.29.1 // indirect
github.com/go-openapi/swag/mangling v0.29.1 // indirect
github.com/go-openapi/swag/pools v0.29.1 // indirect
github.com/go-openapi/swag/stringutils v0.29.1 // indirect
github.com/go-openapi/swag/typeutils v0.29.1 // indirect
github.com/go-openapi/swag/yamlutils v0.29.1 // indirect
github.com/go-openapi/swag/conv v0.29.2 // indirect
github.com/go-openapi/swag/jsonutils v0.29.2 // indirect
github.com/go-openapi/swag/loading v0.29.2 // indirect
github.com/go-openapi/swag/mangling v0.29.2 // indirect
github.com/go-openapi/swag/pools v0.29.2 // indirect
github.com/go-openapi/swag/stringutils v0.29.2 // indirect
github.com/go-openapi/swag/typeutils v0.29.2 // indirect
github.com/go-openapi/swag/yamlutils v0.29.2 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
Expand All @@ -41,14 +41,14 @@ require (
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/yoheimuta/go-protoparser/v4 v4.14.2 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/exp v0.0.0-20260820142414-ca536658362e // indirect
golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba // indirect
golang.org/x/net v0.60.0 // indirect
golang.org/x/sys v0.48.0 // indirect
golang.org/x/sys v0.49.0 // indirect
golang.org/x/term v0.46.0 // indirect
golang.org/x/text v0.42.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260825221802-da73d73af1c5 // indirect
google.golang.org/grpc v1.83.2 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260928230214-8a89bd6388cc // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260928230214-8a89bd6388cc // indirect
google.golang.org/grpc v1.84.0 // indirect
google.golang.org/protobuf v1.36.12 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
)
Loading
Loading