Skip to content

Commit b0fe364

Browse files
authored
ydb-table: add Go SDK audit rules and positive scaffold (#1)
## Summary First Go SDK surface for `ydb-table`: 10 audit rules (`RULE-GO-01..10`) with paired tests, a positive `references/embed/go.md` scaffold, and SKILL.md wired to load both. **Rules** (`skills/ydb-table/rules/embed/go.md`): | ID | Anti-pattern | Severity | |----|--------------|----------| | GO-01 | Reading "all matching rows" through Table Service without pagination (silent 1000-row cap as architectural forcing-function) | Critical | | GO-02 | External state mutation from inside `Do` / `DoTx` retry closure | High | | GO-03 | Missing `WithIdempotent` on `Do` / `DoTx` when work is idempotent | High | | GO-04 | Outer `for` loop wrapping `Do` / `DoTx` (multiplies SDK retry) | High | | GO-05 | Custom retrier with `time.Sleep` bypassing SDK error classification | High | | GO-06 | Nested `Do` / `DoTx` (pool checkout + combinatorial retry) | Critical | | GO-07 | Non-parametrized YQL (`fmt.Sprintf`, string concat) | Critical | | GO-08 | `PreferLocalDC` / `PreferNearestDC` balancer in production | High | | GO-09 | Transaction begin as a separate RPC — split interactive (`WithTxControl` + `BeginTx`) vs non-interactive (`ydb.WithLazyTx(true)`) | Medium | | GO-10 | Transaction commit as a separate RPC — `query.WithCommit()` on the last write, `DoTx` auto-commits on return-nil | Medium | Each rule cites a specific file in `ydb-platform/ydb-go-sdk` (e.g. `retry/mode.go`, `query/client.go`, `balancers/balancers.go`, `MIGRATION_v2_v3.md`). **Positive scaffold** (`skills/ydb-table/references/embed/go.md`) — mirrors `references/embed/java.md`: Stack, Query execution, Transactions, Retries, Bulk upsert, Connection. Patterns lifted directly from upstream examples (`examples/basic/native/query/series.go`, `examples/transaction/query/main.go`, `examples/topic/topicwriter`, `examples/opensource_night2024`). **SKILL.md** — `description:` lists Go SDK symbols as triggers (`ydb.Open`, `db.Query().Do`, `query.WithIdempotent`, `ydb.WithLazyTx`, `ParamsBuilder`, `BulkUpsertDataRows`, balancer names, etc.); Load sources gets writing / auditing Go rows; audit step cites `RULE-GO-NN` alongside `RULE-JV-NN`. **Authoring registry** (`docs/authoring.md`) — `GO` prefix added. **promptfoo config** — the main matrix loads the new Go embed files as skill content; the bare A/B control deliberately remains skill-free; `gpt-oss-20b` `max_tokens` bumped to 8192 (reasoning-model budget was eating the visible answer). ## YDB-specific correction baked in `DECLARE` is **optional** for scalar parameters — types are inferred from `ydb.ParamsBuilder().Param("$x").<Type>(value).Build()`. The `ydb.tech/docs/.../syntax/declare` page still phrases it as mandatory, but upstream Go examples (e.g. `examples/topic/topicwriter/topic_writer_transaction.go` runs `SELECT val FROM table WHERE id=$id` with no DECLARE) show otherwise. RULE-GO-07 Fix and its rubric do not require DECLARE; `references/embed/go.md` notes when DECLARE earns its place (compound `List<Struct<...>>`, explicit caller contract). ## Test plan - [x] Laptop-tier A/B (`promptfoo eval --filter-providers 'Laptop'` main vs bare) confirms skill content is load-bearing on Qwen3.6 35B-A3B for every Go rule. - [x] Smaller laptop models (Devstral, gpt-oss-20b) get the high-level audit right but miss some specific API names / rule-ID citations — capability floor, not rule defect; this is consistent with sibling Java rules. - [x] No foreign-language tokens (`grep -iE 'jdbc|hibernate|spring|java|jpa|python|\.net|dotnet|csharp'`) in either `references/embed/go.md` or `rules/embed/go.md`. - [x] All Source links use direct `github.com/ydb-platform/ydb-go-sdk/...` paths.
1 parent 6a6d974 commit b0fe364

26 files changed

Lines changed: 1183 additions & 11 deletions

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ docs/
4444
- **Two buckets, no mixing.** `references/` is "how to do it right" (no `RULE-` IDs, no severity labels). `rules/` is "what to catch" (must have `RULE-<PREFIX>-<NN>`, severity, what-to-look-for, problem, fix). Don't put advisory prose in `rules/`, and don't put audit anti-patterns in `references/`.
4545
- **`rules/` files are self-contained.** No cross-skill links from `rules/`. The user may install one surface skill without the others; rules must still produce correct audit output. `references/` may link to `../ydb-core/SKILL.md` anchors and to other references in the same skill — relative paths only.
4646
- **YDB-level files stay language-agnostic.** Top-level `references/*.md` (e.g. `working-with-data.md`) and any cross-cutting references must not mention JDBC / Hibernate / Spring / Java / Python / Go / .NET / C++ tokens. Per-language guidance goes in `references/embed/<lang>.md` and `rules/embed/<lang>.md`. Verify with `grep -iE 'jdbc|hibernate|spring|java|jpa|python|golang|\.net|dotnet|csharp'` before committing.
47-
- **Prefix registry.** New rule prefixes must be registered in the table in `docs/authoring.md` on first use. Never reuse an ID or renumber after merge. Currently allocated: `JV` (Java SDK / JDBC / Hibernate / Spring Data).
47+
- **Prefix registry.** New rule prefixes must be registered in the table in `docs/authoring.md` on first use. Never reuse an ID or renumber after merge. Currently allocated: `JV` (Java SDK / JDBC / Hibernate / Spring Data), `GO` (Go SDK — `ydb-go-sdk/v3`).
4848
- **Skill `description:` matches shipped content, not aspirations.** The selector triggers on what's in `description:`. If you list `ydb-go-sdk` in the triggers but the skill has no grounded Go content, the skill will fire on Go code and have nothing useful to load — worse than not firing. Update the description when content lands, not before.
4949

5050
## Git workflow

docs/authoring.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ Workflow inside `SKILL.md` loads **one** tree or the other based on task type (a
6868
**Severity**: Critical | High | Medium | Low
6969
**What to look for**: <grep-friendly signals>
7070
**Problem**: <1–3 lines>
71-
**Fix**:
72-
<short corrected snippet>
71+
**Fix**: <1–2 sentences naming the corrective API call(s), OR a short corrected snippet>
72+
**Source**: <upstream file URL(s) backing the claim>
7373
```
7474

75+
`Fix` may be prose-only when the prose itself names every corrective API the auditor needs (e.g. `query.WithIdempotent()`, `table.TxControl(table.BeginTx(...))`). Reach for a snippet when the fix turns on a non-obvious composition of calls or a config-file shape that prose can't capture (the Java rules' Hibernate `application.properties` block, JPA annotations, Spring meta-annotations). The Go rules ship prose-only after laptop A/B confirmed that adding code blocks did not improve audit quality on smaller models — verify the same on any new surface before going prose-only.
76+
7577
Rules must be self-contained — a surface skill installed without `ydb-core` must still produce correct audit output for its own rules. Do not cross-reference `ydb-core` from `rules/`.
7678

7779
### Cross-references (from `references/` only)
@@ -95,6 +97,7 @@ Rule IDs have the shape `RULE-<PREFIX>-<NN>`. Prefixes are **not pre-allocated**
9597
| Prefix | Scope | First used in |
9698
|--------|-------|---------------|
9799
| JV | Java SDK / JDBC / Hibernate / Spring Data anti-patterns | skills/ydb-table/rules/embed/java.md |
100+
| GO | Go SDK (`ydb-go-sdk/v3`) — driver, sessions, query/table services, retry, transactions | skills/ydb-table/rules/embed/go.md |
98101

99102
### Severity labels
100103

docs/testing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ The tool is [promptfoo](https://www.promptfoo.dev). One declarative `promptfooco
88

99
Every eval runs this shape:
1010

11-
- **System prompt:** the installable skills' content embedded into one system message. `ydb-core` is loaded as a single `SKILL.md`. `ydb-table` is loaded as `SKILL.md` plus its `references/working-with-data.md`, `references/embed/java.md`, and `rules/embed/java.md` — i.e. the full body of the skill, as if the agent had read every Load-Sources entry.
11+
- **System prompt:** the installable skills' content embedded into one system message. `ydb-core` is loaded as a single `SKILL.md`. `ydb-table` is loaded as `SKILL.md` plus its `references/working-with-data.md`, `references/embed/java.md`, `references/embed/go.md`, `rules/embed/java.md`, and `rules/embed/go.md` — i.e. the full body of the skill, as if the agent had read every Load-Sources entry.
1212
- **User prompt:** supplied by the test case (`tests/<skill>/<case>.yaml`).
1313
- **Grader:** `claude-sonnet-4.6` judges each `llm-rubric` assertion against a criterion block written in plain English.
1414

promptfooconfig.bare.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ providers:
125125
model: "openai/gpt-oss-20b"
126126
messages: *messages
127127
temperature: 0.2
128-
max_tokens: 2048
128+
# Reasoning model — same headroom as in promptfooconfig.yaml.
129+
max_tokens: 8192
129130
- id: https:mistralai/devstral-small
130131
label: Laptop · Mistral Devstral Small
131132
config:

promptfooconfig.routing.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ providers:
126126
model: "openai/gpt-oss-20b"
127127
messages: *messages
128128
temperature: 0.0
129-
max_tokens: 256
129+
# Reasoning model — same fix as Qwen3.6 35B-A3B below and the
130+
# main matrix: 256 gets eaten by the thinking budget and the
131+
# visible slug comes back empty. 8192 leaves headroom.
132+
max_tokens: 8192
130133
- id: https:mistralai/devstral-small
131134
label: Laptop · Mistral Devstral Small
132135
config:

promptfooconfig.yaml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ _messages: &messages
6868
6969
--- ydb-table / rules / embed / java.md ---
7070
{{ ydb_table_rules_java }}
71+
72+
--- ydb-table / references / embed / go.md ---
73+
{{ ydb_table_refs_go }}
74+
75+
--- ydb-table / rules / embed / go.md ---
76+
{{ ydb_table_rules_go }}
7177
- role: user
7278
content: "{{ user_prompt }}"
7379

@@ -140,7 +146,10 @@ providers:
140146
model: "openai/gpt-oss-20b"
141147
messages: *messages
142148
temperature: 0.2
143-
max_tokens: 2048
149+
# gpt-oss-20b is a thinking model; 2048 tokens get eaten by the
150+
# reasoning budget and the visible answer comes back empty or
151+
# truncated. 8192 matches the budget given to Qwen3.6 35B-A3B.
152+
max_tokens: 8192
144153
- id: https:mistralai/devstral-small
145154
label: Laptop · Mistral Devstral Small
146155
config:
@@ -178,6 +187,8 @@ defaultTest:
178187
ydb_table_refs_working_with_data: file://skills/ydb-table/references/working-with-data.md
179188
ydb_table_refs_java: file://skills/ydb-table/references/embed/java.md
180189
ydb_table_rules_java: file://skills/ydb-table/rules/embed/java.md
190+
ydb_table_refs_go: file://skills/ydb-table/references/embed/go.md
191+
ydb_table_rules_go: file://skills/ydb-table/rules/embed/go.md
181192
# Hard pre-filter: any output that came back as the defensive
182193
# "[provider error] ..." stub is a fail regardless of what the grader says.
183194
# Without this the grader will happily pass a 400/401 error as a "valid

skills/ydb-table/SKILL.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: ydb-table
3-
description: Writing and auditing code that runs YQL against YDB tables. Use when the user writes a query, designs a table or primary key, reads an `EXPLAIN`, or asks to review Java application code (ydb-java-sdk, ydb-jdbc-driver, Hibernate, Spring Data JPA) that talks to YDB. Triggers on YQL keywords (`UPSERT`, `SELECT`, `DECLARE`, `AS_TABLE`, `VIEW <index>`, `CREATE TABLE`, `ALTER TABLE`, `EXPLAIN`), on the `BulkUpsert` SDK API, on JDBC / Hibernate / Spring symbols (`JpaRepository`, `findAllById`, `saveAll`, `deleteAllByIdInBatch`, `hibernate.jdbc.batch_size`, `@Version`, `@Retryable`, `SQLRecoverableException`, `SQLTransientException`), on YDB transaction-mode names (`SerializableRW`, `SnapshotRO`), and on PostgreSQL / MySQL → YDB conversion prompts. For non-Java SDKs (Go, Python, C++, C#) this skill covers only the YQL / schema / transaction-mode side; SDK-specific guidance for those languages is not in this skill yet — say so and point at upstream docs.
3+
description: Writing and auditing code that runs YQL against YDB tables. Use when the user writes a query, designs a table or primary key, reads an `EXPLAIN`, or asks to review Java (ydb-java-sdk, ydb-jdbc-driver, Hibernate, Spring Data JPA) or Go (`ydb-go-sdk/v3`) application code that talks to YDB. Triggers on YQL keywords (`UPSERT`, `SELECT`, `DECLARE`, `AS_TABLE`, `VIEW <index>`, `CREATE TABLE`, `ALTER TABLE`, `EXPLAIN`), on the `BulkUpsert` SDK API, on JDBC / Hibernate / Spring symbols (`JpaRepository`, `findAllById`, `saveAll`, `deleteAllByIdInBatch`, `hibernate.jdbc.batch_size`, `@Version`, `@Retryable`, `SQLRecoverableException`, `SQLTransientException`), on `ydb-go-sdk/v3` symbols (`ydb.Open`, `db.Query().Do`, `db.Query().DoTx`, `db.Table().Do`, `query.WithIdempotent`, `query.WithCommit`, `ydb.WithLazyTx`, `ydb.ParamsBuilder`, `s.BeginTransaction`, `table.TxControl`, `table.BeginTx`, `BulkUpsertDataRows`, `balancers.PreferLocalDC`, `balancers.PreferNearestDC`), on YDB transaction-mode names (`SerializableRW`, `SnapshotRO`), and on PostgreSQL / MySQL → YDB conversion prompts. For other SDKs (Python, C++, C#) this skill covers only the YQL / schema / transaction-mode side; SDK-specific guidance for those languages is not in this skill yet — say so and point at upstream docs.
44
---
55

66
# YDB Table
@@ -11,7 +11,7 @@ Writing YQL against YDB tables, designing schemas to back those queries, and aud
1111

1212
1. **Classify the task.** Write a new query or schema, audit existing code, convert from another SQL dialect, or read an `EXPLAIN`.
1313
2. **Load sources** per the table below.
14-
3. **Do the work.** When auditing, cite `RULE-JV-NN` for any anti-pattern flagged. When the topic isn't covered by the loaded sources, say so and link to upstream YDB docs rather than guessing.
14+
3. **Do the work.** When auditing, cite the rule ID for any anti-pattern flagged — `RULE-JV-NN` for Java, `RULE-GO-NN` for Go. When the topic isn't covered by the loaded sources, say so and link to upstream YDB docs rather than guessing.
1515

1616
## Load sources
1717

@@ -20,12 +20,14 @@ Writing YQL against YDB tables, designing schemas to back those queries, and aud
2020
| Reads, writes, transaction modes, batch vs bulk | `references/working-with-data.md` |
2121
| Writing Java application code against YDB | `references/embed/java.md` |
2222
| Auditing Java application code against YDB | `rules/embed/java.md` |
23+
| Writing Go application code against YDB | `references/embed/go.md` |
24+
| Auditing Go application code against YDB | `rules/embed/go.md` |
2325
| Schema design — primary key shape, partitioning | `../ydb-core/SKILL.md#schema-basics` |
2426
| YQL syntax, built-in functions, pragmas | <https://ydb.tech/docs/en/yql/reference/> — do not reproduce the spec from memory |
2527

2628
## Content rules
2729

28-
- Always parameterize: `DECLARE` the parameters and bind values. Plan-cache reuse depends on it; concatenated literals miss the cache.
30+
- Always parameterize: bind values through the SDK's typed parameter API (e.g. `ydb.ParamsBuilder()` in Go, `PreparedStatement` in JDBC), do not concatenate them into the query text. Plan-cache reuse depends on it; concatenated literals miss the cache. A leading `DECLARE` block in the query body is optional in modern YDB — scalar parameter types are inferred from the bound values — and earns its place on compound shapes (`List<Struct<...>>`) or as an explicit caller contract.
2931
- Prefer the Query Service over the deprecated Table Service for new code.
3032
- When converting from another SQL dialect, surface where YDB diverges — primary keys are partition keys, no `SERIAL` / `AUTO_INCREMENT`, JOIN behavior and built-in function names differ — rather than producing code that happens to parse.
3133
- Don't fabricate YQL syntax, built-in names, or SDK symbols. If the loaded sources don't cover the question, link the relevant page under <https://ydb.tech/docs/en/yql/reference/> and state the uncertainty.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Embedding YDB in Go applications
2+
3+
## Stack
4+
5+
The only YDB Go SDK is **`github.com/ydb-platform/ydb-go-sdk/v3`**. The same package exposes two surfaces:
6+
7+
- a **native** API with the modern Query Service (`db.Query().Do/DoTx(...)`) and the legacy Table Service (`db.Table().Do/DoTx(...)`),
8+
- a **`database/sql`** driver registered as `"ydb"` (blank-import `_ "github.com/ydb-platform/ydb-go-sdk/v3"`) for code that needs the stdlib interface.
9+
10+
Default new code to the native Query Service. The Table Service is in legacy mode and has a 1000-row default result cap (surfaced as an error on `s.Execute` in v3 by default, restored to v2-style silent truncation if `ydb.WithIgnoreTruncated` is set on the driver — see <https://github.com/ydb-platform/ydb-go-sdk/blob/master/MIGRATION_v2_v3.md>). Connection-string format and authentication environment variables: see [`../../../ydb-core/SKILL.md#connecting`](../../../ydb-core/SKILL.md#connecting). Worked examples for both surfaces: <https://github.com/ydb-platform/ydb-go-sdk/tree/master/examples>. `database/sql` specifics: <https://github.com/ydb-platform/ydb-go-sdk/blob/master/SQL.md>.
11+
12+
## Query execution
13+
14+
Canonical native-API pattern — open the driver once with `ydb.Open(...)`, then run all work inside a `db.Query().Do(...)` closure. The closure is the retry unit: the SDK invokes it again on every retryable error.
15+
16+
```go
17+
db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
18+
if err != nil { return err }
19+
defer db.Close(ctx)
20+
21+
err = db.Query().Do(ctx, func(ctx context.Context, s query.Session) error {
22+
res, err := s.Query(ctx,
23+
`SELECT name FROM users WHERE id = $id;`,
24+
query.WithParameters(ydb.ParamsBuilder().
25+
Param("$id").Uint64(42).Build()),
26+
)
27+
if err != nil { return err }
28+
defer func() { _ = res.Close(ctx) }()
29+
// iterate result sets / rows, build the value inside the closure
30+
return nil
31+
}, query.WithIdempotent())
32+
```
33+
34+
Three load-bearing pieces:
35+
36+
- **`query.WithIdempotent()`** declares the closure safe to replay on *conditionally* retryable failures (connection drop, gRPC reset, session loss). Set on reads and on writes keyed by a client-generated id; do not set on a non-idempotent write such as a counter increment.
37+
- **`query.WithParameters(ydb.ParamsBuilder()...)`** binds values rather than concatenating them. Closes SQL injection and per-distinct-text plan-cache churn. The server infers types from the builder, so a leading `DECLARE` block is optional for scalar parameters — write one only when you want an explicit contract (typically for `List<Struct<...>>` and other compound types) or to fail-fast on a parameter-type mismatch from the caller.
38+
- **All data processing happens inside the closure.** Assign to outer variables only on the success path — the line that returns `nil`. Anything assigned earlier survives across retry attempts and produces wrong values.
39+
40+
Source: <https://github.com/ydb-platform/ydb-go-sdk> README "Example Usage".
41+
42+
## Transactions
43+
44+
YDB has two transaction styles, and `ydb-go-sdk/v3` supports both:
45+
46+
- **Non-interactive** (default for new code) — the SDK manages the transaction inside `db.Query().DoTx(ctx, func(ctx, tx query.TxActor) error { ... })`. Per the upstream `query/client.go` godoc: *"If op TxOperation returns nil — transaction will be committed"*. Open the driver with `ydb.WithLazyTx(true)` so the begin is deferred onto the first query, and pass `query.WithCommit()` to the last write so the commit rides on its RPC — zero standalone begin/commit round-trips.
47+
- **Interactive** — the developer writes the begin and commit explicitly. Same fusing, two shapes depending on statement count:
48+
- *Multi-statement*: first call is `tx, result, err := s.Execute(ctx, table.TxControl(table.BeginTx(table.WithSerializableReadWrite())), firstQuery, params)``txControl` is `s.Execute`'s positional second argument and the begin rides on this RPC. Subsequent calls use the returned `tx` handle. The last call uses `tx.Execute(ctx, lastQuery, params, options.WithCommit())` (where `options` is `github.com/ydb-platform/ydb-go-sdk/v3/table/options`) — the commit rides on the final write's RPC. Canonical form: `table/example_test.go` `Example_lazyTransaction` in upstream.
49+
- *Single-statement*: combine begin and commit on the only `s.Execute`: `s.Execute(ctx, table.TxControl(table.BeginTx(table.WithSerializableReadWrite()), table.CommitTx()), sql, params)` — one RPC carries begin + write + commit. Canonical form: `examples/ttl/series.go`.
50+
- *Query Service* equivalent: `s.Query(ctx, sql, query.WithTxControl(...), query.WithCommit())` — txControl and commit are `ExecuteOption`s on `s.Query(...)`.
51+
52+
Worked non-interactive example: <https://github.com/ydb-platform/ydb-go-sdk/blob/master/examples/transaction/query/main.go>.
53+
54+
For the transaction-mode list (`SerializableRW`, `SnapshotRO`, `StaleRO`, `OnlineRO`) and the consequence for application-level optimistic locking, see [`../working-with-data.md`](../working-with-data.md).
55+
56+
## Retries
57+
58+
`Do` / `DoTx` retry the closure internally; there is no need for an outer `for` loop or a `time.Sleep`-based retrier in caller code. The SDK classifies the error through `retry/mode.go` `MustRetry(isOperationIdempotent bool)`:
59+
60+
- **Non-retryable** — propagated to the caller (`PRECONDITION_FAILED`, schema mismatch, bad parameters).
61+
- **Unconditionally retryable** — always retried regardless of idempotency (`ABORTED`, `OVERLOADED`).
62+
- **Conditionally retryable** — retried only when `WithIdempotent` was passed (transport drops, session loss, timeouts).
63+
64+
Backoff and jitter are built in; configure via retry options on the `Do` / `DoTx` call, not by wrapping.
65+
66+
Source: <https://github.com/ydb-platform/ydb-go-sdk/blob/master/retry/mode.go>.
67+
68+
## Bulk upsert
69+
70+
Use `db.Table().BulkUpsert(ctx, tablePath, rows)` for non-transactional ingest:
71+
72+
```go
73+
err := db.Table().BulkUpsert(ctx,
74+
path.Join(db.Name(), "events"),
75+
table.BulkUpsertDataRows(types.ListValue(values...)),
76+
)
77+
```
78+
79+
For when the bulk API is the right call versus `AS_TABLE` inside a transaction — and when it is forbidden (synchronous secondary indexes, attached changefeeds) — see [`../working-with-data.md`](../working-with-data.md).
80+
81+
Source: <https://github.com/ydb-platform/ydb-go-sdk/blob/master/examples/opensource_night2024/main.go>.
82+
83+
## Connection
84+
85+
See [`../../../ydb-core/SKILL.md#connecting`](../../../ydb-core/SKILL.md#connecting).

0 commit comments

Comments
 (0)