Agent Paranoid Android
User Handbook / Руководство пользователя
Reproducible synthetic test data for CSV and database workflows
Start Here
Agent Paranoid Android¶
English · Русский
Create repeatable test datasets with useful relationships and business rules, without copying source rows. Start with a file, safe database metadata, or an explicit specification, then review the plan before generating fresh values.
Stable 1.6.0 is the recommended release.
Use the CLI below or the runnable
Python API example.
Five-Minute Check¶
python3 -m pip install "agent-paranoid-android==1.6.0"
test-data-agent doctor
test-data-agent demo --output out/demo
The demo uses a bundled fictional fixture. After installation it needs no network, database or AI provider. A healthy installation reports:
quickstart smoke: ok
doctor passed
Choose Your Starting Point¶
| I have | Start here |
|---|---|
| One CSV file | First CSV Dataset |
| Related CSV files | Related Tables |
| PostgreSQL | PostgreSQL Workflow |
| Trino | Trino Workflow |
| A safe profile or a plan | Profiles And Specs |
Generation Or Transformation?¶
Synthetic generation creates new rows from a reviewed DatasetSpec. Use it
for valid, boundary, load or controlled-invalid test cases. The normal process
is profile, review the specification, generate, validate, then
review the output.
Selective transformation keeps one-to-one correspondence with input rows and applies explicit field actions. Its result has mixed origin. Source-value preservation requires a non-sensitive field decision and fresh local-terminal approval of the exact inputs and plan; agents and MCP cannot issue it. Start with Transform Local Data.
Rules And Formats¶
Use business rules for formulas, field conditions, foreign keys and aggregate checks. The source/output matrix shows routes to CSV, JSON, Parquet and generated SQL. SQL export writes a file, not a database.
Advanced Integrations¶
AI, MCP, Containers, and Custom providers
Before Sharing A Dataset¶
Review the specification, validation reports and generation_manifest.json.
For a valid synthetic dataset expect synthetic: true,
source_rows_copied: false and validation_valid: true.
These checks do not certify statistical anonymity or detect every sensitive
value. Explicit mixed/negative datasets can intentionally fail validation.
Database access remains allowlisted, read-only and bounded. AI receives safe metadata, never raw PII, secrets or source rows. See the Safety Model and Troubleshooting.
For offline reading use Downloads. For another release use Documentation Versions. Maintainer and release records live in History And Maintenance.
Installation¶
English · Русский
Stable 1.6.0 is the recommended release. Its signed source, packages and
containers passed public verification.
Requirements¶
- Python 3.11 or newer
- enough local disk space for the requested output
- a dedicated working directory for inputs and generated artifacts
The supported CI matrix covers CPython 3.11, 3.12, 3.13, and 3.14. Python 3.11 remains the minimum so users can adopt newer interpreters without forcing existing environments to upgrade. The notice and release-gate rules for changing this matrix are defined in Runtime And Integration Support.
Read the migration notes before regenerating existing fixtures.
Install From PyPI¶
The stable release is 1.6.0; the commands below
pin that exact version for reproducible installation.
Create an isolated environment:
macOS and Linux¶
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install "agent-paranoid-android==1.6.0"
The base package supports CSV, JSON, and deterministic PostgreSQL SQL export. Add only the source and format integrations you need:
python3 -m pip install "agent-paranoid-android[parquet]==1.6.0"
python3 -m pip install "agent-paranoid-android[mcp]==1.6.0"
python3 -m pip install "agent-paranoid-android[mcp,trino]==1.6.0"
python3 -m pip install "agent-paranoid-android[postgres]==1.6.0"
python3 -m pip install "agent-paranoid-android[openai]==1.6.0"
python3 -m pip install "agent-paranoid-android[gigachat]==1.6.0"
Dependency footprint budgets live in Dependency Compatibility.
The all extra remains available for development, demos, and container builds.
It is not the recommended user installation. Use
test-data-agent doctor --require-extra all to verify that full environment.
The experimental GigaChat adapter is retained in 1.6.0 through its
explicit gigachat extra. Follow
Use The GigaChat Advisor for authentication, mandatory
TLS verification, and the review-first workflow. The default provider remains
OpenAI.
Stable 1.6.0 is the recommended default. Add an optional extra to the same
exact stable pin only when needed.
Windows PowerShell¶
py -3.11 -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install "agent-paranoid-android==1.6.0"
Run the self-contained environment check:
test-data-agent doctor
Expected final lines:
quickstart smoke: ok
doctor passed
doctor uses a temporary fictional fixture and makes no external calls.
Use doctor --require-extra parquet (or another installed extra) for an offline
capability check. See Troubleshooting for
individual checks and CLI automation for JSON
output.
For development setup use Contributing. For documentation builds use Publishing Documentation. Shell completion has its own reference.
Confirm The Installed Version¶
python3 -c "import test_data_agent; print(test_data_agent.__version__)"
The package name is agent-paranoid-android. The command remains
test-data-agent.
Next Step¶
Use First CSV Dataset for one table, Related Tables for a folder containing one CSV per table, or Profile PostgreSQL for an allowlisted database.
First CSV Dataset¶
English · Русский
This tutorial profiles one CSV file, infers a generation specification, generates new values, and validates the result.
Prerequisites¶
- complete Installation;
- run commands from a clone of this repository so the synthetic fixture below is available;
- choose a new output directory.
The fixture contains fictional values and reserved example email domains.
For the same workflow as an executable script with its own synthetic fixture,
run examples/csv_quickstart/run.sh.
Generate 25 Rows¶
test-data-agent generate-from-csv tests/fixtures/customers.csv \
--count 25 \
--seed 12345 \
--format csv \
--output out/customers.csv
Expected summary:
Generated synthetic dataset: out | rows: customers=25 | seed: 12345 | validation: passed | source rows copied: no
The exact output path shown in the summary can vary by platform.
Inspect The Bundle¶
The command writes:
out/
customers.csv
csv_profile.json
dataset_spec.json
generation_manifest.json
validation_report.json
Check the manifest before using the data:
python3 -c "import json; m=json.load(open('out/generation_manifest.json')); print(m['synthetic'], m['source_rows_copied'], m['validation_valid'], m['seed'])"
Expected output:
True False True 12345
Open out/customers.csv and confirm that it contains 25 generated rows plus
the header. Source rows are not shuffled or copied.
Reproduce The Result¶
Generate into a different path with the same seed:
test-data-agent generate-from-csv tests/fixtures/customers.csv \
--count 25 \
--seed 12345 \
--format csv \
--output out/repeated/customers.csv
The two generated CSV files should match:
python3 -c "from pathlib import Path; assert Path('out/customers.csv').read_bytes() == Path('out/repeated/customers.csv').read_bytes(); print('deterministic: ok')"
Use Your Own CSV¶
Replace the fixture path with your file:
test-data-agent generate-from-csv data/customers.csv \
--count 100 \
--seed 12345 \
--format csv \
--output out/customers.csv
Treat every source CSV as potentially sensitive. Do not share its contents, profile artifacts, or command logs until you have reviewed them. The profiler suppresses raw values for fields detected as sensitive, but ambiguous domain fields still require human review.
Exact values remain replaced by default. When customers.status has been
reviewed as a bounded non-sensitive business enum, authorize only that field:
test-data-agent generate-from-csv tests/fixtures/customers.csv \
--local-category customers.status \
--count 25 \
--seed 12345 \
--format csv \
--output out/approved-status/customers.csv
The request fails closed if the field contains PII, secrets, identifiers, quasi-identifiers, free text, excessive cardinality, or long values. The option does not authorize any other field or any external-provider destination.
Review ambiguous identifiers and financial columns before accepting inferred keys or distributions. For exact category limits, distinct-count evidence and identifier behavior, see CSV Profiling Details.
Next, read Review The Output.
Review The Output¶
English · Русский
A successful command is not the end of the review. Use the artifacts in the bundle to decide whether the synthetic dataset is safe and useful.
This page describes synthetic-generation bundles. The gated mixed-origin transformation workflow has a separate review contract: validation does not make its output synthetic, and action provenance and any required exact-snapshot local preservation receipt must also be checked. See Selective Transformation.
Review Order¶
- Read
generation_manifest.json. - Read
validation_report.json. - Read
business_validation_report.jsonwhen business rules were supplied. - Review the effective
dataset_spec.yamlordataset_spec.json. - Inspect a small sample of generated rows.
Manifest Checks¶
For a valid synthetic dataset, require all of these conditions:
{
"synthetic": true,
"source_rows_copied": false,
"validation_valid": true
}
Also confirm:
seedis the value requested by the caller;row_countsmatch the requested scale;output_formatis correct;package_versionanddataset_spec_schema_versionare recorded;spec_sha256is present;business_validation.rules_sha256and its summary are present when rules were used.effective_rulesbinds generation mode, validation settings, relationship, constraint, and distribution counts to the exact spec and business-rule fingerprints without repeating rule values.
Validation Report¶
validation_report.json reports deterministic checks for:
- entity and field schema;
- primary-key uniqueness;
- relationships and foreign keys;
- field and row constraints;
- temporal and formula constraints;
- aggregate reconciliation.
Do not treat a missing report as success. A failed valid-mode run is not an
accepted dataset. Explicit mixed/negative test generation may retain intentionally
invalid rows and their failed validation report in a supported output format;
the CLI reports validation_failed and exit 1. Do not relabel that result valid.
Parquet negative datasets use explicitly marked scalar columns when malformed
cells cannot fit native Arrow types. The bundle reader restores those cells for
validation; their report remains invalid. Ordinary incompatible typed values
still reject the entire export without partial publication. Keep the specification,
manifest and encoding metadata described in the source/output matrix. Privacy failures never authorize publication of source values.
These synthetic manifest checks do not apply to the separately gated selective transformation workflow. Its bundle records mixed origin, action provenance and any exact-input preservation authority; it must not claim fully synthetic or anonymous output. Transformation validation failure prevents publication. See the execution contract.
Assurance Levels¶
Interpret each result at its actual level:
| Level | Evidence | What it does not prove |
|---|---|---|
| Structural validation | Schema, keys, relationships, constraints, formulas, and business rules passed deterministic checks. | Values are private or safe to distribute. |
| Built-in safety policy | The reviewed spec rejected known raw sensitive values, unsafe categories, and disabled safety settings. The report's privacy section records this policy check. |
Detectors found every PII, secret, quasi-identifier, or rare free-text value. |
| Complete-row reuse check | A supported CSV workflow compared generated and available source rows and found no complete-row match. | No individual value, partial row, rare combination, or statistical pattern resembles the source. |
| Domain privacy review | An accountable reviewer assessed the generated artifacts under the organization's policy and intended use. | A formal statistical privacy guarantee unless a separate qualified evaluation provides one. |
validation_valid: true means the enabled deterministic checks passed. It is
not a privacy certificate. Name- and value-based detection is heuristic and
can produce false negatives, especially for domain identifiers,
quasi-identifiers, rare categories, and free text. This project does not assign
an anonymity, differential-privacy, or re-identification-resistance level.
Profile Review¶
Profiles should contain metadata such as types, null ratios, ranges, percentiles, approximate distinct counts, safe low-cardinality distributions, and masked patterns.
Stop and investigate if a profile contains:
- a real email address, phone number, token, credential, or private key;
- a source row copied as a nested object or list;
- rare free-text values that could identify a person;
- an unexpected identifier distribution.
Generated-Row Review¶
Inspect generated data for domain usefulness, but do not compare or publish raw source rows during that review. For sensitive domains, perform review in the same protected environment as the source data.
Current CSV bundles declare csv_encoding: backslash-null-v1 in their manifest.
String cells and headers that could be spreadsheet formulas receive a reversible
\F marker; null is \N, empty text stays empty, and literal leading backslashes
are doubled. Numeric values, including negative numbers, remain numeric. Keep
the manifest for schema-aware bundle decoding; legacy unmarked CSV retains its
previous interpretation. Artifact names supplied through public workflows must
be one safe filename component; separators and parent-directory components are
rejected before any artifact is written. Formula failures expose only fixed
local reasons, never expressions, values, or nested exception text.
Re-run with the same spec, rules, package version, and seed when reproducibility is required. A change to any of those inputs can legitimately change output.
See Safety Model for guarantees and limitations.
How-To Guides
Add Business Rules¶
English · Русский
Use structured YAML or JSON when generated rows must satisfy domain rules. The deterministic rule engine applies and validates the rules; an LLM is not the enforcement mechanism.
For a complete annotated format, see the runnable business-rules reference, including all rule families, condition operators, formula modes, aggregates, scenarios and a matching DatasetSpec. The standalone JSON Schema is generated from the runtime model.
Create A Rule File¶
The checked-in example at examples/orders_rules.yaml contains:
field_rules:
- table: orders
field: status
required: true
allowed_values: [paid, cancelled]
- table: orders
field: amount
required: true
min_value: 0
row_rules:
- type: temporal_ordering
table: orders
start_field: created_at
end_field: fulfilled_at
allow_equal: true
- type: formula
table: orders
field: amount
expression: quantity * unit_price
Rule references must match fields in the effective DatasetSpec. Unknown keys,
tables, fields, rule types, and formula syntax are rejected.
Prepare A Reviewed Spec¶
test-data-agent profile-example tests/fixtures/example_dataset \
--output out/rules/profile.json
test-data-agent infer-spec out/rules/profile.json \
--count 25 \
--output out/rules/dataset_spec.yaml
Review out/rules/dataset_spec.yaml, then generate with rules:
test-data-agent generate out/rules/dataset_spec.yaml \
--seed 12345 \
--format csv \
--business-rules examples/orders_rules.yaml \
--output out/rules/generated
Review:
out/rules/generated/
business_validation_report.json
generation_manifest.json
validation_report.json
The generation manifest records a normalized rule fingerprint, rule counts, pass/fail counts, truncation status, overall business validity, and bounded expected-versus-observed violation counts.
Supported Rule Categories¶
| Category | Use |
|---|---|
| Field rule | Required values, allowed values, numeric bounds |
| Conditional required | Require fields when a condition matches |
| Conditional allowed values | Restrict a field under a condition |
| Temporal ordering | Enforce start/end ordering |
| Formula | Calculate or validate bounded arithmetic |
| Foreign key | Preserve cross-table references |
| Aggregate formula | Validate an aggregate expectation |
| Scenario | Control weighted combinations of field values |
Generate Controlled Invalid Cases¶
Use an explicit generation mode:
test-data-agent generate out/rules/dataset_spec.yaml \
--count 100 \
--seed 12345 \
--format csv \
--mode mixed \
--invalid-ratio 0.02 \
--business-rules examples/orders_rules.yaml \
--output out/rules/mixed_cases
With business rules, mixed uses seeded random row selection at the requested
invalid ratio and attempts an eligible rule violation for each selected row.
The ratio is not an exact count of failed cells or rules. negative attempts
eligible violations for every row; it does not make every field invalid, and
tables without an applicable mutation can remain valid. Keep these datasets
clearly separated from valid fixtures and review the validation report rather
than expecting it to pass.
For tables with several field and row rules, selected rows are distributed
deterministically across required, allowed-value, numeric-bound, conditional,
temporal, and formula violations. Reusing the same seed, mode, ratio, and rule
file reproduces the same negative cases. Foreign-key violations use synthetic
missing parent keys without changing the parent table. Aggregate-formula
violations change only the configured concrete numeric field. Count-style
aggregate rules with field: "*" are validation-only because changing row
counts would also break the dataset shape.
One selected invalid mutation can break several overlapping rules. The engine audits the affected row before and after mutation and includes newly broken local rules in the expected counts. Cross-table rules are checked before and after the injection pass; newly broken rules with a valid baseline are also counted. Injection requires a valid business-rule baseline and refuses an already invalid baseline before introducing negative cases. Standalone validation still reports unplanned failures as unexpected. An injection that does not break its selected rule still reports a missing expected failure. These audits share the normal work and deadline budgets.
The business validation report compares expected and observed violations per
rule. unexpected_violation_count identifies failures that were not selected
by controlled invalid generation; missing_expected_violation_count identifies
selected cases that validation did not observe. expectations_met is true only
when both counts are zero. These fields contain counts only, never generated
row values.
Reproduce The Same Cases Through CLI And MCP¶
The checked-in examples/negative_cases/ bundle fixes the spec, rule file,
seed (1300), mode (mixed), and invalid ratio (0.5). Run it through CLI:
test-data-agent generate examples/negative_cases/dataset_spec.yaml \
--seed 1300 \
--mode mixed \
--invalid-ratio 0.5 \
--format json \
--business-rules examples/negative_cases/business_rules.yaml \
--output out/negative-cli
The MCP equivalent uses the same files after copying the example bundle below
the configured generator workspace. The mode and invalid ratio are already
recorded in dataset_spec.yaml:
{
"name": "generate_dataset",
"arguments": {
"spec_path": "negative_cases/dataset_spec.yaml",
"output_folder": "negative-mcp",
"output_format": "json",
"seed": 1300,
"business_rules_path": "negative_cases/business_rules.yaml"
}
}
Both paths produce identical synthetic row files and matching expected versus observed violation counts. Use separate empty output folders when repeating the example.
Safety Restrictions¶
Do not put real identifiers, emails, phone numbers, addresses, credentials, tokens, or other production literals into rule files. Sensitive-looking literals are rejected by CLI and MCP entry points.
Formula syntax is a bounded arithmetic subset, not Python or SQL. Rule payload size, expression complexity, and estimated row/rule evaluations are limited.
See Configuration for adjustable limits.
Generation ranges and business invariants¶
A field's distribution describes sampling. A formula in assign mode computes
and replaces its target; its result may leave that sampling range. The report
records assignment-domain checks and violations separately from business-rule
validity. Declare a field rule with min_value/max_value when the result must
obey an invariant. Formula check mode validates existing values without
assigning them; use it when replacement would hide the condition you intend to
test. The complete runnable reference linked above includes both modes and
conditional predicates, including null and inclusive range checks.
Scenario weights are relative probabilities, not exact row quotas or predicates that automatically bind a scenario to source rows. A passing rule report checks declared rules; it does not establish source fidelity or discover missing rules. Entity-attribute-value inputs are not automatically pivoted into business fields. Model the desired entities and declare relationships/rules explicitly before using the generation command above.
Conditional formulas and synthetic EAV models¶
A formula accepts an optional typed when condition in either assign or check
mode. A false condition skips the expression entirely, so an unselected branch
cannot divide by zero or overwrite a sampled value. Reports distinguish
eligible_row_count, evaluated_row_count and skipped_row_count; skipped rows
are not passed checks. Rules without when retain their old serialization,
fingerprints and behavior. An explicit null condition value uses the existing
condition semantics: equals: null selects null/missing, numeric ranges do not.
A predicate field absent from the DatasetSpec rejects before generation.
row_rules:
- type: formula
table: observations
field: value
when: {field: attribute, equals: ratio}
expression: numerator / divisor
Predicate fields cannot be row-rule assignment/repair targets. Multiple assigning
formulas for one target require provably disjoint equals/in_values predicates
on the same field; overlapping or unprovable branches reject before generation.
Legacy unconditional assignments retain their previous order. Expressions keep
the existing bounded arithmetic and exact DECIMAL rules; conditions share the
same privacy checks, work allowance and deadline.
The runnable synthetic EAV example
uses a reviewed ratio/total vocabulary, generated identifier domains and two
disjoint exact-decimal formulas. Vocabulary and formulas are authored independently
of source rows. Each observation has one attribute/value; no source pivot,
source-key retention or duplicate merge occurs. Missing observations differ from
nullable values. Declare entity/attribute uniqueness separately if required;
the example intentionally permits repeated generated pairs.
Profile PostgreSQL¶
English · Русский
Database profiling is available in stable 1.6.0 and requires explicit
read-only configuration, allowlists and resource budgets.
Install the optional driver:
pip install "agent-paranoid-android[postgres]"
Configure one explicit read-only scope. The password setting names another environment variable; it is not the password itself.
export POSTGRES_SOURCE_ID=warehouse
export POSTGRES_HOST=db.example.internal
export POSTGRES_DATABASE=analytics
export POSTGRES_USER=test_data_agent
export POSTGRES_PASSWORD_ENV=WAREHOUSE_PASSWORD
export WAREHOUSE_PASSWORD='replace-in-your-shell'
export POSTGRES_ALLOWED_SCHEMAS=public
export POSTGRES_ALLOWED_TABLES=public.customers,public.orders
export POSTGRES_ALLOWED_COLUMNS=public.customers.customer_id,public.customers.status,public.orders.order_id,public.orders.customer_id,public.orders.state,public.orders.amount
For an intentionally table-wide aggregate profile, an entry may instead use
the exact schema.table.* form:
export POSTGRES_ALLOWED_COLUMNS='public.customers.*,public.orders.*'
The parent tables must still appear exactly in POSTGRES_ALLOWED_TABLES.
Before any aggregate runs, bounded PostgreSQL catalog metadata expands each
wildcard into a frozen, sorted explicit-column snapshot. Profiling queries
enumerate quoted column identifiers; they never execute SELECT *. Bare,
schema-wide, table-name, embedded, or over-budget wildcards fail closed.
Declared single-column integer and string primary keys are recognized regardless
of their name (for example, ticket_no or record_code). Generation uses fresh
synthetic identifiers; it does not preserve source keys. Sensitive key fields
retain their sensitivity classification. Reprofile saved artifacts to obtain
this metadata behavior.
Composite primary keys are currently unsupported: profiling rejects them before aggregate scans, including when the column allowlist exposes only part of the key. It never treats one component as a complete unique key. Other primary-key types require an independently reviewed generation specification. Review the complete relational constraints explicitly when authoring that specification; automatic inference does not support composite uniqueness.
If a platform portal supplies a JDBC endpoint, replace only the separate host, port, database, and TLS settings with a credential-free JDBC-style URL:
export POSTGRES_JDBC_URL='jdbc:postgresql://db.example.internal:5432/analytics?sslmode=verify-full'
Keep POSTGRES_USER, POSTGRES_PASSWORD_ENV, every allowlist, and every budget
separate. Userinfo, passwords, unknown query properties, and session-changing
options in the URL fail before a connection is opened. This syntax is parsed
into the existing Psycopg adapter; Java and JDBC drivers are not used. If both
URL and component settings are present, explicitly supplied values must match.
PostgreSQL connections now default to verify-full, which verifies the server
certificate and configured hostname. Configure a trusted CA certificate through
the Psycopg/libpq trust-root configuration (for example PGSSLROOTCERT) and use
a hostname covered by the certificate. Existing installations using the former
require default must configure trust before upgrading. Connection failure does
not fall back to a weaker mode. Explicit require, verify-ca, or disable
requires POSTGRES_ALLOW_INSECURE=true and is intended only for isolated local
testing; these modes do not provide full server identity verification.
The database role must already be read-only. The client also requests a read-only transaction, TLS, statement and lock timeouts, and bounded aggregate results. It accepts no arbitrary SQL and never profiles source rows.
Table profiling retains observed minimum/maximum bounds for non-sensitive
date and timestamp columns in the existing column-summary query. Inferred
generation uses those ranges; timestamp offsets are retained. Sensitive-name
columns do not expose date bounds, and all-null columns have none. Invalid or
inconsistently typed bounds fail profiling rather than silently inventing a
period. Missing bounds elsewhere still require review; this table-profile
behavior does not imply date-bound support for profile-query.
Create a safe profile, review a generation specification, generate, and
validate. Output paths must not already exist unless the command explicitly
supports --overwrite:
test-data-agent profile-postgres --output out/postgres-profile.json
test-data-agent infer-spec out/postgres-profile.json --output out/dataset-spec.yaml
test-data-agent generate out/dataset-spec.yaml --seed 12345 --output out/generated
test-data-agent validate out/dataset-spec.yaml out/generated
test-data-agent export-postgres-sql out/dataset-spec.yaml --seed 12345 --output out/generated.sql
Run the SQL only in the intended local or disposable target database:
psql --set ON_ERROR_STOP=1 --dbname synthetic_target --file out/generated.sql
The SQL file contains one transaction, deterministic quoted CREATE TABLE,
foreign-key, and INSERT statements, PostgreSQL scalar literals, and NULL.
It is built from validated generated records, not profile query rows. Render or
validation failure leaves no partial output file. Repeating export with the
same reviewed spec, seed, package, and recorded environment produces the same
logical SQL; compare files directly when verifying one environment:
test-data-agent export-postgres-sql out/dataset-spec.yaml \
--seed 12345 --output out/generated-second.sql
cmp out/generated.sql out/generated-second.sql
To profile a reviewed relation without creating a database view, put one fully qualified single-table query in a local file:
SELECT o.order_id, o.state, o.amount AS amount
FROM public.orders AS o
WHERE o.order_id < 999999
Keep the same physical schema/table/column allowlists and run:
test-data-agent profile-query query.sql \
--adapter postgres \
--source-id warehouse \
--entity orders_query \
--output out/query-profile.json
test-data-agent infer-spec out/query-profile.json \
--output out/query-spec.yaml
test-data-agent generate out/query-spec.yaml \
--seed 12345 --output out/query-generated
test-data-agent validate out/query-spec.yaml out/query-generated
This generation walkthrough uses direct columns and aliases, all explicitly
allowed above. A derived expression such as amount * 2 can be profiled under
the SQL policy, but automatic infer-spec rejects profiles with unsupported
expression dependencies. Do not infer that the expression is translated into
a generation formula; review a separate supported specification instead.
The query is parsed locally and must stay inside the documented scalar, projection, and filter subset. A no-row schema probe and bounded aggregate wrappers execute in the forced read-only session. The profile contains a query fingerprint but not the SQL text, its literal, backend messages, or query rows.
The equivalent typed Python entry point keeps the query path and database configuration explicit:
from pathlib import Path
import psycopg
from test_data_agent import (
SqlQueryAdapter,
SqlQueryProfileRequest,
profile_postgres_query_source,
)
from test_data_agent.postgres_config import PostgresConfig
request = SqlQueryProfileRequest(
adapter=SqlQueryAdapter.POSTGRES,
source_id="warehouse",
entity="orders_query",
query_file=Path("query.sql"),
)
profile = profile_postgres_query_source(
request,
config=PostgresConfig.from_env(),
driver=psycopg,
)
Exact values remain disabled by default. A bounded, reviewed, non-sensitive business enum can be kept locally with its source-qualified identity:
test-data-agent profile-postgres \
--local-category warehouse.public.orders.state \
--output out/postgres-profile.json
PII, secrets, identifiers, quasi-identifiers, free text, excessive cardinality,
and long values fail closed. Original literals are not sent to providers, MCP,
logs, or errors. A column wildcard is not a local-value policy: exact values
are considered only when the separate, fully qualified --local-category
selector is present and its content checks pass.
The selector authorizes only the bounded value domain and aggregate counts. It does not retain source row order or a mapping that reconstructs source rows. The generated SQL may contain approved values because its input is the validated synthetic dataset.
The same profiling boundary is available from Python:
import psycopg
from test_data_agent.postgres_client import PostgresClient
from test_data_agent.postgres_config import PostgresConfig
from test_data_agent import generate_dataset, infer_dataset_spec, validate_dataset
from test_data_agent.postgres_profiler import dataset_profile_from_postgres
config = PostgresConfig.from_env()
profile = dataset_profile_from_postgres(PostgresClient(config, psycopg))
spec = infer_dataset_spec(profile)
# Review or edit spec here before generation.
rows = generate_dataset(spec, seed=12345)
report = validate_dataset(rows, spec)
assert report.valid
Keep profile and generated artifacts local unless their destination policy explicitly permits otherwise.
For a complete synthetic end-to-end check against a temporary local
PostgreSQL cluster, run the
examples/local_postgres
example. It creates a SELECT-only role, proves that writes are denied, profiles
two related tables, validates deterministic generation, executes the exported
SQL in an empty target database, and removes the cluster. Run
examples/local_postgres/run-jdbc.sh OUTPUT for the same workflow configured by
a placeholder JDBC-style URL, or examples/local_postgres/run-wildcard.sh
OUTPUT for bounded table-qualified wildcard expansion. Run
examples/local_postgres/run-query.sh OUTPUT for the reviewed query-file path.
Profile Through Trino¶
English · Русский
Database profiling is available in stable 1.6.0 and requires explicit
read-only configuration, allowlists and resource budgets.
Install the optional Trino client and, when using MCP, the MCP SDK:
pip install "agent-paranoid-android[trino]"
pip install "agent-paranoid-android[mcp,trino]"
Stable 1.6.0 supports Basic, JWT, Kerberos, GSSAPI, OAuth2 and client
certificates are documented in the
configuration reference. Follow its
runtime secret-indirection, HTTPS verification and local OAuth opt-in rules.
Local contract tests do not establish remote authentication compatibility.
Configure an explicit read-only scope:
export TRINO_HOST=trino.example.internal
export TRINO_PORT=8443
export TRINO_USER=test_data_agent
export TRINO_HTTP_SCHEME=https
export TRINO_ALLOWED_CATALOGS=warehouse
export TRINO_ALLOWED_SCHEMAS=analytics
export TRINO_ALLOWED_TABLE_COLUMNS='warehouse.analytics.orders.*'
export TRINO_DEPLOYMENT_PROFILE=shared-hardened
export TRINO_MAX_INVOCATION_ESTIMATED_SCAN_BYTES=1073741824
TRINO_ALLOWED_TABLE_COLUMNS is optional for compatibility. When set, an
entry is either one exact catalog.schema.table.column or the exact
catalog.schema.table.* form. Wildcards require restricted mode and catalog
and schema membership in the mandatory allowlists. Bounded
information_schema metadata is validated and sorted before the first table
aggregate; the complete column budget is charged in preflight. Executed
profiling SQL still quotes explicit columns and never projects *.
The same endpoint and optional request defaults can come from a credential-free JDBC-style URL:
export TRINO_JDBC_URL='jdbc:trino://trino.example.internal:8443/warehouse/analytics?SSL=true'
export TRINO_USER=test_data_agent
export TRINO_ALLOWED_CATALOGS=warehouse
export TRINO_ALLOWED_SCHEMAS=analytics
The catalog and schema path must match the allowlists. Credentials, tokens,
roles, session properties, proxies, headers, unknown properties, and
SSL=false fail before client construction. This is parsed into the Python
Trino client; it does not install or invoke Java or a JDBC driver. Explicit
component settings may coexist only when their values agree.
The default aggregate-only MCP tools list allowlisted metadata, describe tables, and compute bounded aggregate profiles. They do not return source rows or raw category literals. Table and column profiling share cumulative statement, column, deadline, response, and optional scan budgets.
A wildcard authorizes aggregate profiling scope only. It does not authorize category literals, preserve-as-is, caller SQL stars, row-returning tools, provider payloads, default MCP literals, logs, or errors. Exact table-column entries retain their existing bounded category-summary policy.
Check that the Trino capability is installed, then start the MCP server:
test-data-agent doctor --require-extra trino
test-data-agent-mcp-trino
doctor checks the installed driver, safe-SQL support and configured deployment
budget profile using a local smoke check. It does not validate the selected
endpoint, authentication or catalog/schema allowlists, or contact Trino.
Server startup and tool calls enforce their respective configuration and access
checks; a successful local doctor check does not prove database access.
The explicit opt-in run_safe_select surface is disabled by default. Enabling
it is a separate row-privacy contract: every string is recursively masked, but
allowed non-string source values may remain, so its output is not source-free,
anonymous, or a generated dataset.
Use the checked-in disposable example for a complete profile-to-generation
workflow over Trino's synthetic TPC-H tiny catalog:
examples/local_trino/run.sh /tmp/agent-paranoid-trino-example
Use examples/local_trino/run-jdbc.sh OUTPUT to run the identical disposable
workflow with its endpoint and tpch/tiny defaults supplied in JDBC syntax.
Use examples/local_trino/run-wildcard.sh OUTPUT to exercise bounded
tpch.tiny.nation.* expansion and deterministic field ordering.
Use examples/local_trino/run-query.sh OUTPUT to profile one reviewed local
SELECT as a virtual entity. Query-source mode additionally requires exact
TRINO_ALLOWED_TABLE_COLUMNS entries or a table-qualified wildcard and rejects
unrestricted mode. It stores a fingerprint, not query text, literals, backend
messages, endpoints, or result rows.
The typed Python entry point uses the same environment configuration and policy boundary:
from pathlib import Path
import trino
from test_data_agent import (
SqlQueryAdapter,
SqlQueryProfileRequest,
profile_trino_query_source,
)
from test_data_agent.trino_config import TrinoConfig
request = SqlQueryProfileRequest(
adapter=SqlQueryAdapter.TRINO,
source_id="warehouse",
entity="nation_query",
query_file=Path("query.sql"),
)
profile = profile_trino_query_source(
request,
config=TrinoConfig.from_env(),
driver=trino,
)
The example removes its container on success or failure and leaves only the safe profile, reviewed spec, generated rows, validation report, manifest, and a bounded result summary. See Configuration and MCP Tools for the full limits and tool contracts.
MCP with a username and password¶
Select TRINO_AUTH_METHOD=basic explicitly for username/password login.
The default is none: setting TRINO_USER alone does not send a password.
TRINO_AUTH_SECRET_ENV holds the name of the password environment variable,
not the password. Basic requires verified HTTPS, including local deployments.
1. Prepare the environment and access¶
python3 -m venv /ABSOLUTE/PATH/trino-env
/ABSOLUTE/PATH/trino-env/bin/python -m pip install 'agent-paranoid-android[mcp,trino]'
/ABSOLUTE/PATH/trino-env/bin/test-data-agent --version
/ABSOLUTE/PATH/trino-env/bin/test-data-agent doctor --require-extra trino
Replace /ABSOLUTE/PATH with your absolute path. Doctor checks local installation,
not server login. Obtain the HTTPS host/port, login, approved catalog/schema/table/
column scope and read-only metadata/aggregate grants from your Trino administrator.
The MCP process needs network access, any required VPN and a trusted certificate
chain. A corporate CA must be trusted by the Python/runtime environment; keep
certificate verification enabled.
2. Supply the password to the process¶
If your MCP client supports protected secret injection into child-process
environment variables, configure MY_TRINO_PASSWORD there. Keep the password out
of JSON, repositories, command arguments and chat. A graphical application may
not inherit terminal variables, and a .env file is not loaded automatically.
Restart the MCP server after changing its environment.
A complete macOS option: use Keychain Access to create a password item named
agent-paranoid-android-trino, with its account matching TRINO_USER and your
password. Save this script as /ABSOLUTE/PATH/start-trino-mcp.sh, replacing the
path to the installed server:
#!/bin/bash
# Resolve the password locally; reserve stdout for the MCP protocol.
if ! MY_TRINO_PASSWORD=$(/usr/bin/security find-generic-password \
-s agent-paranoid-android-trino -a "$TRINO_USER" -w 2>/dev/null); then
printf '%s\n' 'Trino password is unavailable in Keychain' >&2
exit 1
fi
export MY_TRINO_PASSWORD
exec /ABSOLUTE/PATH/trino-env/bin/test-data-agent-mcp-trino
Run chmod 700 /ABSOLUTE/PATH/start-trino-mcp.sh. Allow local access to that
item if macOS prompts. Do not enable set -x or print the password. This launcher
resolves the secret at startup without relying on a GUI application's inherited
environment. On other operating systems use the client's protected storage or a
local secret mechanism.
3. Register the server in your MCP client¶
This is the common mcpServers shape; the settings location depends on the client.
Replace all fictional endpoints, usernames and data names locally. This example
uses the Keychain launcher from the previous step:
{
"mcpServers": {
"trino": {
"command": "/ABSOLUTE/PATH/start-trino-mcp.sh",
"env": {
"TRINO_HOST": "trino.example.internal",
"TRINO_PORT": "443",
"TRINO_HTTP_SCHEME": "https",
"TRINO_USER": "your_login",
"TRINO_AUTH_METHOD": "basic",
"TRINO_AUTH_SECRET_ENV": "MY_TRINO_PASSWORD",
"TRINO_ALLOWED_CATALOGS": "warehouse",
"TRINO_ALLOWED_SCHEMAS": "analytics",
"TRINO_ALLOWED_TABLE_COLUMNS": "warehouse.analytics.orders.*",
"TRINO_DEPLOYMENT_PROFILE": "shared-hardened",
"TRINO_MAX_INVOCATION_ESTIMATED_SCAN_BYTES": "1073741824"
}
}
}
}
When the client securely supplies MY_TRINO_PASSWORD instead of using Keychain,
set command directly to
/ABSOLUTE/PATH/trino-env/bin/test-data-agent-mcp-trino.
Secret substitution is client-specific: ${MY_TRINO_PASSWORD} in JSON is not a
universal substitution mechanism.
TRINO_HOST is a host name without a URL scheme or path; use the actual HTTPS
port. Catalog/schema allowlists are mandatory comma-separated sets. Column scope
is optional for ordinary table profiling, but required for profile-query.
You may replace warehouse.analytics.orders.* with comma-separated exact columns.
The wildcard permits bounded aggregate profiling only, grants no source-row
access and does not replace Trino grants.
The cumulative scan limit shown is 1 GiB per invocation. Existing defaults also
bound request timeout to 30 seconds, execution time to 30 seconds, run time to
45 seconds and scanning to 1 GiB per query. TRINO_CATALOG and TRINO_SCHEMA
are optional defaults within the allowlists. See the
configuration reference for all settings.
4. Verify startup and diagnose failures¶
Restart the server in your MCP client and check that Trino tools appear. Start
with an allowed metadata tool such as list_catalogs, then describe_table for
an approved table. Process startup and Doctor success do not prove authentication.
These instructions are checked locally against configuration contracts, not
against your remote server.
For a 401, check basic, the variable referenced by TRINO_AUTH_SECRET_ENV,
the login and process restart locally. For a 403, check server grants and access
policy; a status alone does not establish the exact cause. For TLS failures,
check the endpoint and certificate trust.
For support share the package version, launch method, TRINO_AUTH_METHOD,
TRINO_HTTP_SCHEME, whether a login and secret reference are set, whether the
password variable reaches the process, and whether another client can log in.
Do not share login/password values, complete .env files, connection URLs,
source rows or raw driver responses.
Authentication failures¶
For a failed connection, record the installed package version and selected
TRINO_AUTH_METHOD locally. Share only those details when investigating a failure;
do not share passwords, tokens, connection URLs or raw driver responses.
A reported HTTP 401 alone does not identify a configuration or compatibility issue.
SQL-query profiling converts untyped HTTP 401/403 and TLS failures into the fixed
SQL query source profiling failed error, without retaining the original
exception cause or context. The CLI keeps its external_service category and
leaves an existing output artifact unchanged. MCP returns its fixed Trino error
and records value-free audit diagnostics. These boundaries do not establish
successful authentication against a particular server.
Transform Local Data¶
English · Русский
Use selective transformation when each output row must correspond to an input row. Unlike synthetic generation, the result has mixed origin and may contain explicitly replaced or approved preserved source values. Treat the destination as potentially sensitive; validation is not an anonymity certificate.
Choose An Action For Each Field¶
| Action | Effect |
|---|---|
drop |
Remove the field. |
synthesize |
Generate new values using the declared generation policy. |
substitute |
Apply an explicit typed mapping, optionally shared by a domain. |
replace_text |
Apply explicit exact-text mappings. Field mappings override file-wide mappings without cascading. |
preserve |
Retain an eligible non-sensitive field only after exact local approval. |
For an unmatched mapping, select rejection, synthesis or eligible preservation explicitly. A preserve fallback has the same approval requirements as direct preservation. Explicit mapped replacements may equal another source value, including a sensitive permutation; this is not permission for implicit copying. Mapping values never belong in logs, summaries, provider requests or MCP replies.
Review Before Execution¶
- Prepare a valid behavior policy, source and any local mapping files. Use a new destination distinct from every input.
- Run
transform-review SOURCE POLICY.yaml. Review the value-free field decisions and record the displayedsnapshot_sha256. - To edit an already valid policy locally, use
transform-review SOURCE POLICY.yaml --decide --edit-actions, thenSAVE. Review the saved bytes again. Saving is not approval. - If any action preserves values, obtain the receipt in your own interactive
local terminal with
transform-approve SOURCE POLICY.yaml RECEIPT --snapshot-sha256 SHA. - Execute with
transform-execute SOURCE POLICY.yaml DESTINATION --snapshot-sha256 SHA, adding--receipt RECEIPTwhen required. Inspect provenance and validation.
SOURCE, POLICY.yaml, RECEIPT, DESTINATION and SHA above are placeholders,
not a ready-to-run dataset approval. Use installed COMMAND --help for options.
Never supply real data to a provider while preparing the policy.
Conditions For Preservation¶
Every preserved field needs an explicit non-sensitive decision, no positive or conflicting sensitivity evidence, and a bounded operator comment. Sensitive, unknown and disputed fields remain blocked. DECIMAL preservation is blocked by default. Approval binds the exact source, classification, policy and referenced mapping bytes. Any bound input change requires fresh review and approval.
Only the controlling local terminal can issue the receipt. Piped confirmation, an agent flag and MCP approval cannot replace it. A matching receipt permits only its reviewed plan; it does not authorize another dataset.
Multiple Inputs And Databases¶
Use a common saved profile
with transform-batch for multiple inputs and final linked validation. Creation
saves configuration only. Validation and execution consume the exact reviewed
digest and any required local receipt.
Configured SQL sessions use administrator allowlists and read-only budgets to capture once. Later steps reuse the same frozen snapshot without reconnecting. Sessions enforce admission, expiry and cleanup. MCP consumers stay workspace confined and return metadata, not rows.
See the CLI contract for formats and arguments, MCP permissions for integration rights, and Configuration for schemas and budgets. Historical RC anchors remain valid links.
Integrations
Connect An MCP Client¶
English · Русский
These workflows describe stable 1.6.0. Start with a workspace-confined
server and enable only tools required for your task. For local preservation
approval use Transform Local Data; MCP cannot issue it.
The project exposes two MCP servers with separate trust boundaries:
- the generator's ordinary file tools use one workspace; configured SQL transformation sessions additionally own private temporary captures;
- the Trino server's default aggregate-only tools provide allowlisted, read-only metadata and profiling.
Start with the generator server. Add Trino only when database profiling is required.
Before enabling tools, use MCP Permissions for the complete tool inventory, required filesystem/network/database rights, client confirmation policy, and separate transformation approval requirements. These are stdio servers: the client launches a local process; no inbound port or MCP OAuth scope is required. Client tool approval, operating-system access, database grants and human dataset review are separate controls.
For process and dependency isolation, use the separate hardened images in Container Deployment. The generator example has no network, while the Trino worker receives no generator workspace mount.
For Trino username/password setup, use the complete Basic authentication MCP example.
Generator-Only Quickstart¶
Install the optional MCP support in a dedicated environment. Use the version selected in Installation.
python3 -m venv /path/to/mcp-env
/path/to/mcp-env/bin/python -m pip install "agent-paranoid-android[mcp]"
mkdir -p /path/to/synthetic-workspace
Desktop clients may not inherit your shell's PATH. Configure the absolute executable path and restart the client after changing its configuration:
{
"mcpServers": {
"test-data-agent-generator": {
"command": "/path/to/mcp-env/bin/test-data-agent-mcp-generator",
"env": {
"TEST_DATA_AGENT_WORKSPACE_ROOT": "/path/to/synthetic-workspace"
}
}
}
}
Replace both absolute paths with your own. The client should discover
plan_dataset, inspect_dataset_plan, approve_dataset_plan, and
recover_dataset_plan. This local workflow requires no database or AI-provider
credentials. The mcpServers example applies to clients supporting that
configuration format; use your client's equivalent server settings otherwise.
Create customers.csv inside the workspace with this fictional fixture:
customer_id,email,status
1,alice@example.com,active
2,bob@example.com,paused
Ask your assistant: "Plan four synthetic customers from customers.csv with seed
81. Show me the specification for review before generating files."
The corresponding plan_dataset arguments are:
{
"source_path": "customers.csv",
"workspace_path": "agent/customers",
"source_type": "csv",
"count": 4,
"seed": 81,
"output_format": "csv",
"table_name": "customers"
}
The response has approval_required: true and spec_path. No generated dataset
exists yet. Open the spec artifact locally and review field types, privacy,
relationships, count, and seed. Inspection is a read-only operation:
{"workspace_path": "agent/customers"}
Call inspect_dataset_plan with those arguments. After a human reviews and
explicitly approves the exact current specification, call
approve_dataset_plan with:
{
"workspace_path": "agent/customers",
"reviewed_spec_sha256": "<review.current_spec_sha256 from inspection>"
}
Replace the placeholder with the actual fingerprint. If the specification
changes, inspect and review it again; a copied fingerprint is not human approval.
The approval response should report row_counts: {"customers": 4},
validation_valid: true, and paths to output, manifest, validation report, and
approval receipt. Inspect the same workspace again to confirm phase: completed.
Report these summaries and paths; do not attach or inline dataset rows.
Resume An Existing Synthetic Plan¶
If the client closes after planning, keep the agent workspace and resume the same conversation through the client's normal session-resume action. Restore the same verified installation, workspace root, MCP connection and tool filter. Keep the existing model, authentication, sandbox and confirmation policy. Run only one copy of that client session.
For the Codex CLI, the upstream client command is codex resume SESSION_ID;
replace SESSION_ID with the existing conversation's identifier. This is a
Codex command, not an Agent Paranoid Android option. If the original launch
supplied MCP settings only for that invocation, reapply those same settings
through the reviewed client launcher when resuming. A bare resume command does
not establish that the required server and tool filter were restored.
Continue with inspect_dataset_plan for the existing workspace. Do not replay
plan_dataset, delete the plan, or choose a new workspace merely to clear a
non-empty-directory refusal. A launcher refusing to create a second plan does
not establish that the package or final-commit checks failed.
When the phase is awaiting_approval:
- Inspect the current plan and make the entire current
dataset_spec.yamlavailable for the human to open and read. Check both its file bytes andreview.current_spec_sha256against the specification being reviewed. - Obtain fresh, explicit human consent for that exact current specification. A model's summary, copied fingerprint, bootstrap prompt, general release authorization or consent sent before the final specification was prepared does not complete this review.
- Immediately before approval, inspect and check the same file again. Changed bytes require another full-file view and renewed consent.
- Call
approve_dataset_planwith the unchanged reviewed fingerprint, thenvalidate_datasetand inspect the completed workspace. Report validation, counts and artifact paths without returning rows.
Client-session resume and recover_dataset_plan are different operations.
For an interrupted approval, follow the state returned by inspection: report
an existing completed result, use recovery only when next_action requests
it, and stop for inspection on an unexpected state. Resuming a conversation
does not itself approve a dataset or authorize preservation. See the
permission boundaries.
Corrective Next Steps¶
- Missing executable or MCP extra: check the absolute path, install
[mcp]into that environment, and restart the client. - Rejected workspace path: move the input inside the configured root and use relative paths. Do not expand permissions to bypass the boundary.
- Non-empty planning directory: inspect the existing plan and resume its review. Use a new workspace only when deliberately starting a separate dataset.
- Stale review fingerprint: inspect, review the changed specification, and obtain renewed human approval before submitting its current fingerprint.
- Interrupted approval or a lost response: inspect first. If
phaseiscompleted, report the existing result. Ifnext_actionisrecover, callrecover_dataset_planwith the workspace and reviewed fingerprint. Recovery retains published outputs without generating another dataset. If inspection requests review and approval, follow that state instead. - Fixed argument-validation or transport-limit error: correct arguments against the discovered tool schema or reduce request size. Do not disable budgets or expect rejected values to be reflected in error messages.
Add Trino only for database profiling, using the separate configuration and Safe Trino Sequence below. Keep database credentials in the Trino server for that aggregate-profile-to-synthetic workflow. The separately configured SQL transformation session has its own connection requirements.
Prepare A Workspace¶
Common-Profile Workflow¶
Stable 1.6.0 provides common_transformation in the generator console
server. Registration grants no dataset permission or preservation approval.
Stable acceptance has finite recorded limits;
changed activation still needs its own review.
It accepts operation (review, validate, execute), workspace-relative
profile, and positive explicit max_total_bytes, max_review_bytes,
max_output_bytes. Validation/execution require the exact reviewed
snapshot_sha256. Preservation additionally requires a pre-existing local
receipt; MCP cannot issue it. Optional destination is execute-only and names
a new direct-child output bundle. Without it, execution is temporary.
The workspace root comes from server configuration, never tool arguments.
Responses contain value-free review/summary metadata, not output rows or mapping
literals. Existing transport/work budgets still apply; these byte settings do
not enlarge source-free profiling or serialized response budgets. Unknown
arguments, including root and approved, are rejected without reflection.
Configuration creation and human confirmation remain local CLI operations.
Installed fictional acceptance with MCP SDK1/SDK2 does not authorize private
data access or issue a local preservation receipt.
mkdir -p /path/to/synthetic-workspace
Inputs, safe profiles, reviewed specs, rules, and outputs used through generator file tools must remain below this directory. Server-owned temporary storage, audit logs and authentication files have separate administrator-configured locations. The workspace setting is an application path boundary, not an operating-system sandbox.
MCP Client Configuration¶
Use the installed console commands:
{
"mcpServers": {
"test-data-agent-generator": {
"command": "test-data-agent-mcp-generator",
"env": {
"TEST_DATA_AGENT_WORKSPACE_ROOT": "/path/to/synthetic-workspace",
"TEST_DATA_AGENT_MCP_MAX_INVOCATION_SECONDS": "120"
}
},
"test-data-agent-trino": {
"command": "test-data-agent-mcp-trino",
"env": {
"TRINO_HOST": "trino.example.internal",
"TRINO_PORT": "443",
"TRINO_USER": "synthetic_data_reader",
"TRINO_HTTP_SCHEME": "https",
"TRINO_ALLOWED_CATALOGS": "hive,iceberg",
"TRINO_ALLOWED_SCHEMAS": "test_data,staging",
"TRINO_QUERY_MAX_EXECUTION_TIME": "30s",
"TRINO_QUERY_MAX_RUN_TIME": "45s",
"TRINO_QUERY_MAX_SCAN_PHYSICAL_BYTES": "1GB"
}
}
}
}
Give the Trino identity only the required metadata and SELECT access through
database grants; no write or administration rights are needed. Catalog/schema
allowlists do not create those grants. TRINO_ALLOWED_TABLE_COLUMNS narrows
safe table profiling, but is not a universal per-tool ACL for metadata, counts,
rule probes or optional run_safe_select. Use database grants for strict
table/column isolation; see the permission matrix.
Do not place a password or token directly in a committed MCP configuration. Use the client's secret mechanism or an environment injected by the runtime.
Safe Generator Sequence¶
For selective transformation review, call review_transformation with
workspace-relative input_path, policy_path and optional table_name.
It reads a fixed local snapshot in the format selected by the saved policy and
returns review_only, snapshot_sha256 and the same value-free review as CLI
transform-review. Referenced mapping files stay local to the policy directory.
The tool writes no artifacts, creates no approval receipt, executes no
transformation and connects to no database. It is separate from ordinary
source-free generator operations.
The stable 1.6.0 generator registers execute_transformation
with workspace-relative input_path, policy_path, new output_path, mandatory
snapshot_sha256, optional table_name/existing receipt_path, and optional
max_total_input_bytes/max_output_bytes run caps. It consumes the same exact
snapshots and budgets as CLI execution and returns transformation_completed,
digest, provenance and budget summaries, never dataset rows or mapping literals.
Explicit replacements may permute sensitive source values under the same
field-independent contract. Review retains a value-free sensitivity note;
mapped values stay in the selected local artifact, never MCP responses. This
does not grant direct preservation or an implicit copy fallback.
Preservation requires a matching receipt issued separately by the human local controlling-terminal CLI. There is no MCP receipt issuer or approval flag. Changed inputs invalidate receipts; workspace escapes, existing destinations, unsupported actions and budget violations fail closed without copying fallback. Registration does not authorize a dataset. Changed activation requires fresh independent safety review and executable evidence. Changed public activation still requires matching contracts, executable safety evidence and independent exact-SHA review. A receipt never authorizes database access or external APIs.
- Put a CSV file, CSV folder, or safe profile below the workspace root.
- Call
plan_datasetwith that source, a new agent workspace, count, seed, and output format. - Stop and review the written
dataset_spec.yaml. - Call
inspect_dataset_planand recordreview.current_spec_sha256. - Call
approve_dataset_planwith that exact fingerprint only after review. - Report summaries and artifact paths, not generated rows.
Use profile_csv, infer_dataset_spec, generate_dataset, and
validate_dataset separately when an advanced client needs control over each
pipeline stage. Direct generate_dataset and export_dataset do not require a
planning approval argument; configure the client's confirmation policy before
enabling these writing tools. Permission to invoke approve_dataset_plan is
not evidence that the human reviewed the displayed specification.
For the planning/approval workflow, embed business_rules in the reviewed
DatasetSpec. Direct generate_dataset and export_dataset calls can instead
provide business_rules_path or a bounded structured business_rules_payload.
Use one rule source: external rules cannot be combined with embedded rules.
Generator MCP reads newline-framed requests through the same bounded transport
used by Trino MCP. Each request receives a fresh non-resettable budget. The
default boundary rejects raw frames above 1 MiB, JSON deeper than 100 levels,
JSON with more than 10,000 structural nodes, or an individual scalar above
256 KiB before MCP/Pydantic materialization. Complete JSON-RPC responses are
limited to 4 MiB and overflow becomes a fixed local error.
Typed argument-validation failures also become the fixed
Tool arguments failed validation error; rejected caller values and nested
Pydantic diagnostics are not returned.
Malformed typed requests are rejected before SDK dispatch with fixed
Invalid request parameters text, and malformed notifications are dropped;
their caller-controlled values do not enter SDK logs or retained exceptions.
Each server process admits at most 32 active requests. Excess requests receive
a fixed bounded capacity error, and disconnect or teardown clears retained
request state. Trino execution is separately capped at eight concurrent
operations per process.
Safe Trino Sequence¶
The default aggregate-only tools are source-literal-free and contain only metadata and aggregate profiling operations:
list_catalogs,list_schemas,list_tables,describe_table;profile_table,profile_table_safe,profile_column;profile_foreign_key,profile_temporal_ordering,profile_formula_rule;profile_conditional_required,profile_conditional_allowed_values;profile_aggregate_mapping.
Catalog and schema discovery returns only names present in the configured
allowlists. Tables may be listed only after their catalog and schema pass those
allowlists. Backend-controlled driver and enumeration failures are exposed as
the fixed Trino request failed error without retaining the original text.
This default aggregate-only surface has no row-returning diagnostic. Its successful responses, validation and database errors, and metadata-only audit records do not contain source-cell literals.
- Call
list_catalogs,list_schemas, andlist_tables. - Call
describe_table. - Call
profile_table_safefor an allowlisted table. - Pass that response to generator
plan_trino_datasetwith a new workspace, explicit count, seed, and output format. - Stop and review the written
dataset_spec.yaml. - Call
inspect_dataset_planand recordreview.current_spec_sha256. - Call
approve_dataset_planwith that value asreviewed_spec_sha256only after the human reviewed that exact spec fingerprint. - Do not export or relay source rows.
Both catalog and schema allowlists are mandatory by default. HTTPS is the default. Plain HTTP requires an explicit override and is intended only for an isolated local Trino instance.
The explicit opt-in row-returning tool run_safe_select is not exposed by
default. Trusted clients that need it must set TRINO_ENABLE_SAFE_SELECT=true.
The review-first planning sequence above does not require it. Its bounded
row-shaped result masks every string, including names and addresses missed by
heuristic classification, plus non-string fields or values recognized as
sensitive. Other non-string source values may remain, so enabling it does not
make returned rows source-free, anonymous, or suitable for relay to an LLM or
generated output.
Expected Result¶
The default generator and default aggregate-only Trino tools return compact metadata:
rows: customers=25, orders=25
seed: 12345
validation: passed
synthetic: true
source rows copied: false
Generated files stay in the workspace. These default tools do not return dataset or source rows; explicit opt-in row-returning tools are outside this expected result.
Failure Conditions¶
The server rejects:
- paths outside the workspace, including existing symlink escapes;
- existing output files and non-empty output directories;
- unrestricted SQL, DDL, DML, joins, CTEs, and subqueries;
- likely PII projections and raw sensitive rule literals;
- non-Trino or oversized inline planning profiles;
- DatasetSpec input passed to
plan_datasetinstead ofgenerate_dataset; - missing Trino allowlists;
- requests exceeding configured input, output, query, or execution limits.
See MCP Tools and Configuration for details.
Preservation approval is never an MCP capability. The registered separate workspace execution consumer cannot issue local receipts, return rows or broaden source-free generator authority. Changed public activation requires the scoped safety review and executable evidence specified by ADR-0020 and ADR-0021.
Configured SQL Sessions¶
The running generator server registers configured_query_session with an
instance-owned session manager. Use only an authorized administrator-configured
PostgreSQL or Trino source. A saved batch profile and
bounded query references
are workspace files; tool arguments never select endpoints or credentials.
| Operation | Arguments | Result and lifetime |
|---|---|---|
open |
profile, references, positive max_total_bytes, max_review_bytes, max_output_bytes |
Capture once; return metadata review, opaque handle, digest, expiry and local approval descriptor. |
review |
handle |
Reuse the same frozen batch; no database reconnection. |
validate |
handle, exact snapshot_sha256 |
Validate temporary output; retain the session until expiry or close. |
execute |
handle, exact snapshot_sha256, new direct-child destination |
Verify any required local receipt, validate and publish; close the session. |
close |
handle |
Remove owned snapshots and receipts; the handle cannot be reused. |
Responses contain review/summary metadata, never captured rows, query text,
mapping literals or connection secrets. local_approval contains an owned
temporary root, batch.yaml, a fixed receipt filename, digest and input/review
limits. These references help the local operator invoke the existing CLI:
test-data-agent transform-batch approve /owned/root batch.yaml local-session-receipt.json \
--snapshot-sha256 REVIEWED_DIGEST \
--max-total-input-bytes REVIEWED_INPUT_LIMIT --max-review-bytes REVIEWED_REVIEW_LIMIT
Use the exact metadata values while the session is alive. The CLI opens the controlling terminal for confirmation; MCP has no approval operation or boolean. This descriptor itself grants no authority. Direct or fallback preservation requires a valid exact receipt; explicit mappings retain their separate safety checks. Changed local bytes cannot produce a receipt for the frozen batch.
Expiry, refusal and shutdown remove owned inputs and receipts. Execution retains only the selected validated output bundle inside the parent workspace. Expired or closed handles refuse without silently recapturing. Start a new explicit session and review its new digest if another capture is needed. Cumulative byte admission is not refunded on close or failure; restart the owning server only after resolving the refusal and reviewing its configured limits.
Cleanup failure returns a fixed incomplete-cleanup error and latches the owner unhealthy; further work refuses. Preserve the failure evidence and inspect local temporary storage before restarting. Default bounds and overrides are documented in configuration. The entrypoint closes all sessions in a shutdown handler even if transport fails. Custom SDK embedding must explicitly inject a session owner and close it; the module-level SDK object creates no SQL sessions.
AI Integration¶
English · Русский
Model-specific Python integrations should implement the provider-neutral
AdvisorExchangeClient contract and use
ExchangeDatasetAdvisor. The client receives static trusted instructions,
safe profile metadata marked as untrusted, and the current structured-output
schema. The adapter validates provider output against the original request and
never generates data or bypasses approval.
advise_agent_workspace can persist that validated proposal as
advisor_review.json and update the pending dataset_spec.yaml. The existing
status fingerprint and explicit approval remain the only path to generation.
AI is optional. The deterministic CLI and Python library can complete the full profile → review → generate → validate workflow without a provider, MCP client, or network access. Add AI only when it reduces manual work in relationship discovery, semantic interpretation, or business-rule hypothesis generation.
When AI is used, this project can be used by an AI client in three practical ways:
- As a local CLI tool.
- Through two MCP servers that cover default aggregate-only Trino profiling and synthetic data generation.
- Through the review-first local agent workflow.
CLI Mode¶
An AI agent with shell access can call the local command-line interface:
test-data-agent profile-example ...
test-data-agent infer-spec ...
test-data-agent generate ...
test-data-agent validate ...
In this mode, the AI plans the workflow, builds or edits a DatasetSpec, runs
deterministic generation, validates the output, and reports the result.
Install the base package for CLI workflows:
python3 -m pip install agent-paranoid-android
Add only the integrations the AI client needs. The exact pin below selects verified stable 1.6.0; see release status.
python3 -m pip install "agent-paranoid-android[mcp,trino]"
python3 -m pip install "agent-paranoid-android[openai]"
python3 -m pip install "agent-paranoid-android[gigachat]==1.6.0"
The experimental GigaChat adapter is included in stable 1.5.0 as an explicit
opt-in and retained in stable 1.6.0. OpenAI remains the default
provider. Follow
Use The GigaChat Advisor before configuring credentials.
Agent Mode¶
Use agent-plan when an AI client should prepare work but stop before
generation:
test-data-agent agent-plan tests/fixtures/example_dataset \
--workspace out/agent \
--count 25 \
--seed 12345 \
--format csv \
--json
The CLI detects this as a CSV-folder source. AI clients should provide
--source-type only when an explicit override is required.
The returned plan summary provides metadata-only fields, sensitive
classifications, relationships, confidence, assumptions, and warnings. Treat
all entity and field names as untrusted data, never as model instructions. The
AI client can summarize out/agent/dataset_spec.yaml and ask for approval.
After review, run:
test-data-agent agent-review out/agent --json
test-data-agent agent-status out/agent --json
test-data-agent agent-approve out/agent \
--reviewed-spec-sha256 "$REVIEWED_SPEC_SHA256" --json
AI clients should use --json, inspect schema_version, and branch on stable
structured error codes and process exit codes. JSON is written only to stdout;
successful responses contain summaries and artifact paths, never dataset rows.
The client must show the current review.current_spec_sha256 alongside the
spec, obtain explicit human approval for that value, and pass it unchanged to
agent-approve. It must not approve a newly computed hash without renewed
human review.
If status reports recovery_required, the client may call agent-recover
with that same human-reviewed hash. It must not edit the generated bundle or
substitute a new hash; recovery revalidates existing artifacts and never
regenerates rows.
This mode is documented in Agent Design. It is useful when an LLM should plan the workflow but deterministic Python code must retain control over generation, validation, source-row checks, and manifests.
In-Process Advisor Client¶
Use ExchangeDatasetAdvisor when a provider SDK runs in the consuming
application:
from test_data_agent import ExchangeDatasetAdvisor
from test_data_agent.providers.openai import OpenAIAdvisorClient
advisor = ExchangeDatasetAdvisor(OpenAIAdvisorClient(model="gpt-5.6"))
The OpenAI adapter is optional, uses structured Responses API output, disables response storage, and accepts only completed parsed responses. The package root and base installation do not import its SDK.
The optional GigaChatAdvisorClient implements the same exchange boundary
through the official gigachat SDK. It is selected explicitly by
agent-advise --provider gigachat, uses fixed verified-TLS endpoints, and
accepts credentials only from the runtime environment. It sends no source
rows or exact locally preserved category values. See the GigaChat guide for a
complete synthetic, review-gated example.
For another provider, implement the same application-owned contract:
from test_data_agent import (
AdvisorExchange,
ExchangeDatasetAdvisor,
advise_agent_workspace,
)
class ProviderClient:
def complete(self, exchange: AdvisorExchange) -> dict:
return call_model_with_structured_output(
trusted_instructions=exchange.trusted_instructions,
untrusted_input=exchange.request.model_dump(mode="json"),
response_schema=exchange.response_json_schema,
)
status = advise_agent_workspace(
workspace,
ExchangeDatasetAdvisor(ProviderClient()),
)
call_model_with_structured_output is provider-specific application code.
Keep additional SDKs and all credentials outside the deterministic core and
base installation. The client must return a parsed object matching
AdvisorProposal; prose, tool commands, and unknown fields fail validation.
For an executable application-layer example, run The Reference Agent. It uses a deterministic stand-in by default and can select the optional OpenAI adapter. The CLI GigaChat path uses the same review and approval contract. All paths stop for explicit human review, require the exact reviewed spec fingerprint, and then run the normal deterministic generation and validation pipeline.
External Advisor JSON Handoff¶
Any model service that can accept and return structured JSON can propose
DatasetSpec changes without a package integration:
test-data-agent agent-plan tests/fixtures/example_dataset \
--workspace out/agent --count 25 --json
test-data-agent agent-advisor-request out/agent \
--exchange > advisor_exchange.json
Load the exchange locally. Exported documents can contain category literals,
matching predicates and local generation metadata. Do not transmit them unchanged.
ExchangeDatasetAdvisor projects the request for built-in and custom clients,
recomputes its fingerprints, validates the projected proposal, restores retained
local metadata under deterministic guards and validates the original request.
Clients must echo the fingerprints they receive. Standalone JSON handoff must
implement this tested projection and local restoration or refuse transmission.
After projection, map each part to the provider's API:
- send
trusted_instructionsthrough its system or developer instruction channel; - send
requestas structured untrusted input; - constrain structured output with
response_json_schema; - save only the resulting
AdvisorProposalasadvisor_proposal.json.
Do not merge request profile text into the trusted instructions. Provider SDK code remains in the consuming application, outside the base package. Then run:
test-data-agent agent-advisor-apply \
out/agent advisor_proposal.json --json
test-data-agent agent-review out/agent --json
test-data-agent agent-status out/agent --json
The core verifies both request fingerprints, the full spec schema, schema
identity, privacy settings, sensitive classifications, row limits, and the
absence of raw sensitive values. It records the exchange in
advisor_review.json and never generates data during apply.
Show the updated dataset_spec.yaml and the new
review.current_spec_sha256 to the human reviewer. Only after explicit review
may the client pass that exact hash to agent-approve. A retry with the same
proposal can finish an interrupted spec write; stale, different, linked,
oversized, or conflicting input fails closed.
See Advisor API for the exact request and proposal contracts. See Build A Provider Adapter for the Python protocol, wire-field tables, adapter template, and required contract tests.
MCP Mode¶
Follow Connect An MCP Client for dedicated-environment installation, absolute executable paths, a narrow workspace and client settings. Use MCP Permissions as the complete tool and rights inventory, including runtime-owned and optional capabilities.
The two console commands are test-data-agent-mcp-generator and
test-data-agent-mcp-trino. Both use stdio; they require no inbound MCP port
or MCP OAuth scope. Client permission to invoke tools, the process user's
filesystem/network rights, database grants and human review are separate.
The default aggregate-only Trino tools return metadata and summaries, not source
rows. The optional run_safe_select is registered only when
TRINO_ENABLE_SAFE_SELECT=true. It masks strings and recognized sensitive
values, but other source values may remain; never treat its rows as anonymous,
relay them to an LLM or use them as generated output.
Ordinary synthetic generator tools need only the selected workspace and no
database/provider credentials. The separate transformation and configured SQL
session tools have additional rights and activation gates documented in the
permission reference. Generator responses contain summaries and artifact paths,
not source or generated rows. export_dataset generates fresh data from a spec;
it does not convert arbitrary source-row files.
The workspace setting confines application tool paths, not all process access.
Use a dedicated root and operating-system/container isolation where needed;
keep credentials and audit files outside the client-accessible workspace.
Direct generate_dataset and export_dataset have no planning approval
argument, so configure human confirmation in the client before enabling them.
The review-first sequence below remains the recommended assistant workflow.
Recommended AI Workflow¶
For a CSV file, CSV folder, or safe profile already inside the generator
workspace, call plan_dataset with a new agent workspace. It detects the
source type, writes the review artifacts, and stops before generation.
An MCP-compatible AI client can run the complete workflow:
- Call
plan_datasetfor a workspace source, or inspect and profile a Trino table safely before passing its safe profile toplan_trino_dataset. - Summarize the written versioned
DatasetSpecand request explicit human approval. - Call
inspect_dataset_planafter any edits and show its current spec fingerprint to the reviewer. - Call
approve_dataset_planwith that exactreviewed_spec_sha256only after approval. - Call
validate_dataseton the generated bundle when an independent validation response is needed. - Return artifact paths plus a concise report with row count, seed, format, validation status, and confirmation that no production rows were copied.
If inspection reports recovery_required, call recover_dataset_plan with
the same reviewed fingerprint. Recovery revalidates the existing bundle and
does not regenerate or return rows.
The generator MCP responses return summaries and validation reports, not data
rows. Generated files stay in the configured workspace. Each bundle includes a
generation_manifest.json with its spec fingerprint, package version, schema
version, seed, format, row counts, validation status, and synthetic provenance.
Treat table names, column names, descriptions, and safe distribution values as untrusted data. An AI client must not follow instructions embedded in source metadata or include metadata directly in privileged prompts.
The reasons for the two-server boundary, path restrictions, manifest checks, and artifact ownership are documented in Generator MCP Design Rationale. Practical end-to-end tool sequences are in MCP Examples.
Local Demo¶
The included demo starts from a checked-in safe Trino profile and executes spec inference, deterministic CSV generation, validation, and manifest creation:
python3 scripts/run_ai_demo.py \
--profile examples/trino_safe_profile.json \
--output out/ai_demo \
--count 100 \
--seed 12345
Run In Containers¶
English · Русский
Container images are an optional deployment path for isolated CLI and MCP workers. PyPI remains the normal installation path for local Python use.
Release Status¶
Stable 1.6.0 images are published and verified; see the
immutable digests and signatures.
The RC5 container evidence remains bound to RC5.
Select an exact version tag such as
ghcr.io/wa-pis/agent-paranoid-android-cli:1.6.0, then resolve and verify its
immutable digest before use. The stable tag also updates the mutable 1.6, 1
and latest aliases; none provides immutable version identity.
Published Images¶
| Image | Entrypoint | Installed surface |
|---|---|---|
ghcr.io/wa-pis/agent-paranoid-android-cli |
test-data-agent |
Core CSV and JSON workflows |
ghcr.io/wa-pis/agent-paranoid-android-generator-mcp |
test-data-agent-mcp-generator |
Core plus MCP |
ghcr.io/wa-pis/agent-paranoid-android-trino-mcp |
test-data-agent-mcp-trino |
Core, MCP, Trino, and SQLGlot |
Release tags publish linux/amd64 and linux/arm64 manifests. PyArrow is not
installed in these images. Use the PyPI parquet extra when Parquet output is
required.
Pull requests build and run every target on both architectures. ARM64 checks
use QEMU only as CI execution support; the resulting image still reports
arm64 and must pass the same non-root, read-only, network-isolated health
contract as the native AMD64 validation. Both architectures also run actual
installed CLI generation, validation and seeded replay in JSON, CSV and SQL;
generator MCP profiling, inference, generation, validation and export over
stdio; and Trino MCP discovery plus an excluded-catalog refusal before network
access. Evidence records the source commit and image digest. The minimal images
also prove a safe missing-Parquet-extra refusal. Live database acquisition is a
separate disposable-database campaign, not a health-check claim.
Build Locally¶
Build only the target you need:
docker build --target cli -t agent-paranoid-android:cli .
docker build --target generator-mcp -t agent-paranoid-android:generator-mcp .
docker build --target trino-mcp -t agent-paranoid-android:trino-mcp .
The Dockerfile uses digest-pinned Python and uv images, a frozen lockfile, and
separate dependency sets. Final images run as UID/GID 65532 by default.
The shared runtime layer installs fixed Bookworm PCRE2 and Perl packages and
checks their versions during the build. Perl remains a Debian essential package;
image scans continue to block fixable High and Critical findings.
Prepare Compose¶
Create writable workspace and audit folders plus a private audit key file:
umask 077
mkdir -p workspace audit/generator audit/trino secrets
openssl rand -base64 32 > secrets/generator_audit_hmac_key
openssl rand -base64 32 > secrets/trino_audit_hmac_key
chmod 600 secrets/generator_audit_hmac_key secrets/trino_audit_hmac_key
export CONTAINER_UID="$(id -u)"
export CONTAINER_GID="$(id -g)"
CONTAINER_UID and CONTAINER_GID must remain non-zero. They let the
non-root process write to bind-mounted host folders on Linux. Never commit the
secrets, audit, or workspace folders.
Build the Compose targets from the current checkout:
docker compose build cli generator-mcp trino-mcp
docker compose run --rm cli doctor --skip-smoke
The Compose contract applies a read-only root filesystem, drops all
capabilities, enables no-new-privileges, limits CPU, memory, processes, and
temporary storage, and publishes no ports.
Generator MCP¶
The generator receives only /workspace and /audit; it has no network:
docker compose run --rm -T generator-mcp
Set TEST_DATA_AGENT_MCP_MAX_INVOCATION_SECONDS in the shell or Compose .env
file before starting generator MCP to configure its invocation deadline. The
default is 120 seconds; finite positive values are required. Independent generation,
profiling, transformation and container memory limits still apply.
An MCP client can launch that command directly. Use an absolute Compose path:
{
"mcpServers": {
"test-data-generator": {
"command": "docker",
"args": [
"compose",
"-f",
"/absolute/path/agent-paranoid-android/compose.yaml",
"run",
"--rm",
"-T",
"generator-mcp"
]
}
}
}
The client receives MCP messages over stdio. There is intentionally no exposed HTTP port.
Trino MCP¶
Set an HTTPS endpoint and narrow allowlists before starting the Trino worker:
export TRINO_HOST=trino.example.internal
export TRINO_PORT=443
export TRINO_USER=test_data_agent
export TRINO_ALLOWED_CATALOGS=iceberg
export TRINO_ALLOWED_SCHEMAS=dev,staging
docker compose run --rm -T trino-mcp
Missing host or allowlists fail before the server starts. The Trino service has network access but receives no generator workspace mount. The Compose example does not enable unrestricted access, plain HTTP, or the optional raw-SQL tool.
Audit Secret¶
Compose mounts separate generator and Trino audit keys below /run/secrets.
Keys are not stored in image metadata or process environment. The application
rejects a secret file that is empty, oversized, writable by another user,
linked, or configured together with TEST_DATA_AGENT_AUDIT_HMAC_KEY.
The services also use separate host directories and logs:
audit/generator/generator.jsonl and audit/trino/trino.jsonl. A compromise of
one worker therefore does not grant the key or writable log mount of the other.
Stop the corresponding writer before rotating either file. See
MCP Audit Logging.
Verify A Published Image¶
Use the immutable digest shown by GHCR rather than relying on a mutable tag:
IMAGE=ghcr.io/wa-pis/agent-paranoid-android-generator-mcp
DIGEST=sha256:replace-with-published-digest
cosign verify \
--certificate-identity-regexp \
'^https://github.com/wa-pis/agent-paranoid-android/.github/workflows/containers.yml@refs/tags/v[0-9].*$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
"${IMAGE}@${DIGEST}"
gh attestation verify "oci://${IMAGE}@${DIGEST}" \
--repo wa-pis/agent-paranoid-android
docker buildx imagetools inspect "${IMAGE}@${DIGEST}" \
--format '{{ json .SBOM }}'
The release workflow signs the multi-platform manifest digest with a short-lived GitHub OIDC identity and publishes BuildKit SBOM and provenance attestations. No Cosign private key is stored in the repository.
Pull-request CI also scans every native container target for fixable High and Critical operating-system and Python-package vulnerabilities. A finding at either severity blocks publication through the container validation gate. Unfixed upstream findings remain visible in the scan output and must be reviewed separately during release-candidate security review.
Health Semantics¶
The image health command performs only local checks: non-root execution, expected dependencies, workspace access, Trino safety configuration, and audit configuration. It never connects to Trino or reads a dataset. Because MCP uses stdio, container liveness is also represented by the MCP process itself.
Reference
Reference Index¶
English · Русский
Start with a task guide when you need a complete workflow. Use these references for exact options, schemas and integration contracts.
Commands And Automation¶
- CLI command index and workflow recipes
- JSON automation, errors and exit codes, shell completion
- Configuration and budgets, resource limits
Data Contract¶
- Source/output matrix and generation modes
- DatasetSpec fields, schema compatibility
- CSV profiling details
- Relationships
- Migration notes and compatibility aliases
- Public stability, runtime support, dependency compatibility
Integrations¶
- MCP tools, permissions, audit logging
- Advisor API, GigaChat, custom advisor, semantic provider, reference agent
Further Reading¶
Choose An Approach¶
English · Русский
Agent Paranoid Android is for teams that need deterministic test datasets from bounded CSV, PostgreSQL, or Trino evidence without copying source rows. Its primary interfaces are the CLI and Python library. Database clients, MCP, and AI providers are optional integrations around the same review and validation boundaries.
The database workflows below are available in stable 1.6.0.
Quick Comparison¶
| Need | Best starting point | Why |
|---|---|---|
| A safe, repeatable dataset from profiled structure and reviewed rules | Agent Paranoid Android | Profiles bounded evidence, generates fresh values, validates executable rules, and records a seed and manifest. |
| One PostgreSQL table or Trino table with a known schema | Exact component configuration and exact table/column allowlists | This is the stable, narrowest database-source path. It keeps executed profiling work explicit and aggregate-only. |
| A platform-supplied JDBC connection string | JDBC-style endpoint input plus separate credentials, allowlists, and budgets | It reuses the Python adapter and accepts endpoint syntax only; it does not add Java or a JDBC driver. |
| Every column in one approved table | Qualified column wildcard | schema.table.* or catalog.schema.table.* expands through bounded metadata into explicit columns; executed SQL never projects *. |
| One reviewed derived relation from a single table | profile-query |
A strict local-file SELECT becomes one aggregate-only virtual profile. It is not an arbitrary SQL runner and never returns query rows. |
| A few hand-authored values or one simple object factory | Faker or an application fixture factory | Less setup when you already know every field and do not need profiling, review artifacts, or dataset validation. |
| Application-native fixtures coupled to ORM models and lifecycle hooks | A framework fixture factory | Better fit when model constructors and database callbacks are the contract being tested. |
| Production-like statistical fidelity with formal privacy targets | A specialist statistical synthesizer plus a privacy evaluation | This project does not certify anonymity, differential privacy, or resistance to every re-identification attack. |
| A masked or reduced copy of production | A governed masking/subsetting system | Use only when policy permits retaining real rows; this project deliberately generates fresh rows instead. |
Choose This Project When¶
- source access must stay read-only and metadata-focused;
- generated rows must be reproducible from an explicit seed;
- foreign keys, temporal order, formulas, and business rules must be executable and independently validated;
- humans must approve inferred specifications before generation;
- CSV, JSON, SQL, or Parquet output needs an evidence manifest.
Start with the offline installed demo:
test-data-agent demo --output out/demo
Choose Something Else When¶
Use a simpler factory when manually defining every field is cheaper than profiling and review. Use a specialist privacy system when you need a measured privacy guarantee. Use governed masking only when retaining source rows is an explicit requirement and is allowed by your data policy.
No approach removes the need to review sensitive identifiers, rare free text, quasi-identifiers, and organization-specific privacy requirements.
Profiles And Specs¶
English · Русский
Profiles and specifications have different roles.
Safe Profile¶
A profile describes source structure without becoming a copy of the source dataset. It can contain:
- field names and inferred types;
- null ratios and approximate distinct counts;
- numeric ranges and percentiles;
- date and timestamp ranges;
- safe distributions for non-sensitive low-cardinality fields;
- string length statistics and masked sensitive patterns;
- inferred relationship and constraint candidates.
A profile must not contain source rows, raw PII, credentials, tokens, or rare free-text values. Exact values are disabled by default. An explicit field-scoped local allowlist may retain a reviewed bounded non-sensitive business enum or constant after content, cardinality, and value-length checks.
Create one from a CSV folder:
test-data-agent profile-example data/example_dataset \
--output out/profile.json
For example, retain a reviewed local enum while replacing every other source literal:
test-data-agent profile-example data/example_dataset \
--local-category orders.status \
--output out/profile.json
This authorization remains local. External advisors receive deterministic field-scoped labels, and default MCP responses do not receive the exact enum.
SQL Query Source¶
This source type is available in stable 1.6.0.
One reviewed local query file can shape a PostgreSQL or Trino virtual entity:
test-data-agent profile-query query.sql \
--adapter postgres \
--source-id warehouse \
--entity paid_orders \
--output out/profile.json
SQL source policy 1.1 accepts exactly one fully qualified, single-table SELECT
with explicit projections or an authorized qualified wildcard, bounded filters,
and a small deterministic scalar-expression set. It rejects joins, CTEs,
subqueries, set operations, windows, table functions, commands, volatile or
unknown functions, multiple statements, and unauthorized references before
derived aggregate work begins.
It also accepts aliased SUM, COUNT, MIN, MAX and AVG projections,
optionally grouped by explicit authorized source columns. Each other selected
column must be a grouping key. COUNT(*) counts rows; it is not a row wildcard.
Aggregate arguments may use the existing scalar expressions, but nested or
wrapped aggregates, DISTINCT aggregates, HAVING, grouping expressions/ordinals,
ROLLUP and grouping sets remain unsupported. Grouped/aggregate queries referencing
sensitive-name source columns fail closed even when renamed. Existing budgets
and disclosure checks remain; small groups are not an anonymity guarantee.
For example, SELECT status, COUNT(*) AS measured FROM public.orders GROUP BY
status profiles a grouped relation without fetching its rows.
Query profiles also record has_unmodeled_expressions: a source-dependent
non-column projection or any aggregate (including COUNT(*)) sets it to true. Profiling remains available, but
infer-spec rejects such profiles rather than silently generating independent
values that break SQL-expression dependencies. Direct column aliases remain
eligible. Older SQL profiles missing the marker must be reprofiled before
automatic inference. Non-query legacy profiles retain prior inference behavior.
The optional marker defaults to null (unknown); unknown does not change legacy
profile fingerprints, while explicit true/false is included in the fingerprint.
This does not translate SQL into formulas or authorize raw query-result access.
The profile records source_fingerprint and source_policy_version, not SQL
text or literals. The adapter performs a no-row schema probe followed by
bounded aggregates. Query result rows are never returned, persisted, sent to a
provider or MCP, or supplied to generation.
DatasetSpec¶
DatasetSpec is the reviewed, executable generation contract. It contains:
- entities, fields, types, nullability, and row counts;
- primary keys and relationships;
- distributions and constraints;
- privacy annotations;
- structured business rules;
- generation and validation settings and schema version.
Infer a spec:
test-data-agent infer-spec out/profile.json \
--count 100 \
--output out/dataset_spec.yaml
Review the spec before generation. Inferred relationships and constraints are candidates, not unquestionable facts.
Generation¶
Generation reads the specification, not source rows:
test-data-agent generate out/dataset_spec.yaml \
--seed 12345 \
--format csv \
--output out/generated
The seed belongs to the generation request and is recorded in the effective spec and manifest.
Validation¶
test-data-agent validate out/dataset_spec.yaml out/generated \
--output out/generated/validation_report.json
Validation is deterministic Python code. An AI client may plan or summarize the workflow, but it is not the only validator.
Versioning¶
Newly constructed DatasetSpec files use schema_version: "1.1"; version
1.0 remains supported, and serialized files without a version load as 1.0
for compatibility. Exact DECIMAL fields require 1.1. Keep the schema version,
package version, spec_sha256,
business_validation.rules_sha256, and seed with any dataset that must be
reproduced later.
The complete field reference is in DatasetSpec.
Date and time bounds¶
A reviewed date_range or datetime_range supplies sampling bounds. Missing
endpoints use 2020-01-01 and 2025-01-01. Supply both ordered endpoints for an
earlier or later period: a partial bound that reverses the effective interval
now rejects with a recovery hint. Generation keeps previous output artifacts
unchanged on this failure.
Datetime sampling retains its whole-second offset policy and the lower endpoint's microseconds. Very long fractional intervals use integer duration arithmetic to stay within the maximum. Range endpoints alone do not establish monthly or other calendar granularity; source-period fidelity remains unmeasured.
Safety Model¶
English · Русский
The central invariant is:
Generated output must contain newly generated values, not copied source rows.
Source data may be read to derive bounded metadata. It is not used as a pool of rows to shuffle, duplicate, or export.
Trust Boundaries¶
Selective transformation is a separate mixed-origin surface in stable 1.6.0. Its execution and approval contract
requires local interactive approval of exact input/review bytes before any
explicitly non-sensitive field can be preserved. Agent execution can only
consume an existing matching receipt; it cannot issue or broaden approval.
Sensitivity conflicts, unknown fields and default DECIMAL preservation remain
blocked. Receipt integrity does not prove personhood or anonymity. Existing
generation, profiling and default responses retain their source-free contracts.
Private implementation review does not activate public registration.
Treat all of these as untrusted:
- CSV, JSON, YAML, and Parquet files;
- paths supplied to CLI or MCP tools;
- profile payloads supplied by another process;
- business-rule files and inline rule payloads;
- Trino identifiers, metadata, query results, and environment variables;
- PostgreSQL and Trino JDBC-style endpoint strings;
- local PostgreSQL and Trino SQL query-source files;
- output directories that may contain symlinks or existing files.
Defenses¶
Sensitive data¶
Likely PII and secrets are detected from both field names and values. Sensitive columns suppress raw top values and expose masked patterns or aggregate metadata instead. Sensitive examples use an opaque placeholder rather than intentionally preserving source values. Non-sensitive category profiles replace source values with ranked synthetic labels by default. An explicit field-scoped local allowlist may preserve only a reviewed bounded non-sensitive business enum or constant after content, cardinality, and value-length checks. Rare free text, PII, secrets, identifiers, and quasi-identifiers are never eligible.
Approved exact values may appear only in local profiles, reviewed specs, deterministic generated rows, and local SQL export. External providers receive field-scoped labels, and default MCP responses, logs, and public errors remain source-literal free.
Source-row reuse¶
Generation uses a reviewed specification and a local seeded random generator. Runtime checks reject exact source-row reuse in supported CSV workflows. The comparison covers complete rows only and runs only when the source CSV is available to that workflow. It does not detect every partial-value, quasi-identifier, or statistical similarity between source and output.
Filesystem¶
Input and output paths must be distinct. New bundles are assembled in a temporary sibling directory and published only after size and validation checks. Workspace-bound MCP paths reject traversal and symlink escapes.
Trino¶
Trino access is read-only, allowlisted, bounded by client row limits and
server-side time and scan budgets. Unsafe query shapes and likely sensitive
projections are rejected before execution. The default aggregate-only tools
return only source-literal-free metadata and aggregates. The explicit opt-in
row-returning tool run_safe_select recursively masks every returned string in
bounded scalar or composite values and any non-string field or value recognized
as sensitive. Other non-string source values may remain, so those rows are not
source-free or anonymous.
PostgreSQL¶
Direct PostgreSQL profiling uses the optional driver through a forced
read-only session. Schema, table, and column allowlists are mandatory, and one
shared statement/result/deadline budget bounds metadata and aggregate queries.
Normal table profiling accepts no caller SQL and reads no source rows.
profile-query is a separate local-file surface for one strictly parsed,
single-table, fully allowlisted SELECT. Adapter-owned no-row schema and
aggregate queries profile its virtual relation without fetching result rows.
The profile stores a SHA-256 fingerprint and policy version, never query text,
query literals, backend messages, endpoints, or source rows. Qualified local
category selectors may retain only values that pass the selective local policy
above.
PostgreSQL schema.table.* and Trino catalog.schema.table.* column selectors
are authorization syntax, not SQL. They are expanded from bounded metadata for
one exact allowed table into a deterministic explicit-column snapshot before
aggregates run. They do not authorize source rows, local exact values, category
literals, caller projection stars, providers, default MCP literals, logs, or
errors.
PostgreSQL and Trino may accept credential-free JDBC-style endpoint syntax. Parsing happens before client construction and rejects userinfo, secrets, session-changing or unknown properties, malformed escapes, ambiguous paths, and conflicting component configuration. The complete URL is discarded after normalization and is never written to profiles, manifests, MCP responses, provider payloads, logs, or public errors.
Resource limits¶
The project limits input bytes, rows, columns, cells, YAML complexity, Parquet expansion, generated rows, output bytes, available disk reserve, rule work, query work, and wall-clock generation time.
What The Project Guarantees¶
For supported synthetic-generation workflows and accepted inputs, the project is designed to:
- avoid copying complete source rows;
- avoid writing raw detected PII into safe profiles;
- regenerate identifiers and sensitive semantic values;
- produce logically deterministic output for the same spec, rules, seed, locale, runtime, dependencies, serializer, and generator version;
- validate schema, relationships, constraints, and business rules;
- record provenance and safety flags in a generation manifest.
The manifest records those effective inputs plus SHA-256 evidence for generated artifacts. Byte-for-byte identity is expected only when the complete recorded environment is unchanged. It is not guaranteed across Python, dependency, serializer, operating-system, or package versions, even when logical values and validation results remain equivalent.
What It Does Not Guarantee¶
The project cannot decide whether every ambiguous business field is sensitive. It also cannot prove that an inferred distribution is legally or statistically safe for every use case. The project does not currently implement differential privacy, k-anonymity, l-diversity, or a privacy budget, and makes no statistical privacy guarantee. Treat generated data as requiring a domain-specific privacy review before distribution.
Human review is still required for:
- domain-specific identifiers and rare free text;
- inferred relationships and constraints;
- privacy requirements outside the built-in detectors;
- organization-specific retention and access controls;
- downstream systems that may log or redistribute generated data.
Do not send production data, raw PII, credentials, or tokens to an LLM while reviewing profiles or specifications.
Acceptance Checklist¶
Before publishing a generated dataset:
This checklist applies to synthetic generation, not the gated mixed-origin transformation workflow. A transformed bundle must not be relabelled synthetic merely because validation passed: its action provenance and any matching local preservation receipt remain separate requirements.
- manifest says
synthetic: true; - manifest says
source_rows_copied: false; - deterministic validation passed;
- business validation passed when rules were used;
- seed, row counts, format, and fingerprints are correct;
- profile and generated samples contain no unexpected sensitive values;
- the output is stored outside the source path.
See Review The Output for the practical review sequence.
Configured SQL Transformation Sessions¶
The separately selected configured query workflow captures one allowlisted read-only result using administrator configuration, then reviews and validates frozen local bytes without reconnecting. It does not expand ordinary profiling or source-free generation authority. MCP returns only metadata and consumes an existing exact local controlling-TTY receipt when preservation requires one; it cannot issue approval. Session handles expire without recapture, owned raw inputs/receipts are removed, and only validated selected output is retained. Cleanup failure refuses further work. Registration is not data access permission or final exact-SHA security/release clearance.
Help
Troubleshooting¶
English · Русский
Start with:
test-data-agent doctor
test-data-agent doctor --json
The final line should be doctor passed.
Require the optional capability you intend to operate:
test-data-agent doctor --require-extra parquet
For Parquet this performs a local temporary generation and read-back, checks
row counts and manifest safety flags, and contacts no external service. A
missing extra recommends installation. An installed extra whose local smoke
fails reports a capability failure instead of recommending reinstall; check
local setup and rerun doctor. A broken dependency import is reported as an
import failure, not as an absent package. Exception text and temporary paths
are omitted.
If quickstart generation fails, earlier dependency checks remain in the report
and doctor --json returns ok: false, exit code 1, and a failed quickstart
check without exposing the underlying exception.
doctor --require-extra mcp constructs the real generator FastMCP
transport, registers one local audited probe tool, and verifies its public tool
listing. It does not start a server, listen on a port, invoke the tool, or
contact an MCP client.
doctor --require-extra trino validates a bounded allowlisted query with the
installed Trino SQL parser, constructs a client for the reserved
doctor.invalid host, and closes it without opening a cursor or executing SQL.
It does not read Trino credentials or contact a coordinator. A missing extra
gets installation guidance; a local smoke failure does not establish a missing
package or remote connectivity problem.
doctor --require-extra openai constructs and closes the installed SDK client
with a local non-secret placeholder and verifies the structured Responses API
used by the advisor adapter. It does not read OPENAI_API_KEY, send a request,
or contact the provider. A local smoke failure does not establish a missing
package or a problem with deployment credentials.
doctor --require-extra gigachat uses a local fake SDK client to verify strict
structured-response mapping and cleanup. It does not read
GIGACHAT_CREDENTIALS or GIGACHAT_ACCESS_TOKEN, obtain a token, or contact
GigaChat. Install stable 1.6.0 with the gigachat extra.
See release status.
JDBC-Style URL Rejected¶
JDBC-style endpoint input, qualified column wildcards, and profile-query are
available in stable 1.5.0 and retained in stable 1.6.0.
Use only the documented credential-free PostgreSQL or Trino shape. Keep users, password references, tokens, roles, headers, proxies, session properties, allowlists, and budgets in their existing settings. Remove duplicate or unknown URL properties. When URL and component fields are both set, make the explicit host, port, database/TLS or catalog/schema values identical, or remove one representation. Errors intentionally omit the URL and conflicting values.
An endpoint also fails when the URL exceeds 4,096 UTF-8 bytes, its host exceeds 253 characters, a PostgreSQL database identifier exceeds 63 characters, or a Trino catalog/schema identifier exceeds 255 characters. Shorten the local configuration; the rejected value is intentionally absent from the error.
Qualified Column Wildcard Rejected¶
Use exactly schema.table.* for PostgreSQL or
catalog.schema.table.* for Trino. Keep the parent schema/table or
catalog/schema allowlists present. Trino wildcards require restricted mode.
Bare *, schema-wide forms, embedded stars, empty or duplicated metadata,
schema drift, and expansion beyond the configured column budget fail before
aggregate profiling. Replace the wildcard with reviewed exact columns when
the table is wider than the intended profiling scope.
SQL Query Source Rejected¶
Pass one UTF-8 file to profile-query; SQL text is not accepted in an option
or environment variable. SQL source policy 1.1 permits one fully qualified,
single-table SELECT with explicit output aliases, bounded filters, and the
documented deterministic scalar subset. Remove joins, CTEs, subqueries, set or
window operations, table functions, comments, volatile/unknown functions,
multiple statements, and unauthorized tables or columns.
Aliased SUM/COUNT/MIN/MAX/AVG and explicit-source-column GROUP BY are allowed. Other selected columns must be grouping keys. Remove nested/wrapped aggregates, DISTINCT aggregates, HAVING, grouping expressions/ordinals and grouping sets. Sensitive-name source references remain blocked for grouped/aggregate queries, even with renamed outputs. An accepted aggregate profile is not permission to fetch result rows or automatically infer a dependency-preserving generation spec.
The query file, AST, projected fields, and adapter work must remain inside all configured budgets. A changed file, unsupported type, malformed backend metadata, schema drift, or budget exhaustion fails closed and leaves no profile. Errors intentionally omit SQL text, literals, endpoints, and backend messages; inspect the local reviewed file and allowlists instead.
Transformation Rejected¶
Stable 1.6.0 provides the common-profile CLI/MCP workflow. See the CLI workflow.
Published 1.5.0 does not include this command. Registration grants no dataset
permission. The finite fictional transformation/session campaign is recorded in
stable evidence; it grants no blanket dataset consent.
If the snapshot no longer matches, review the saved inputs, policies and mappings again; validate and execute with the newly returned digest. A receipt for an earlier snapshot cannot authorize the changed one. When preservation is selected, obtain a matching receipt through the separate local terminal workflow; an agent or MCP client cannot issue one.
For a budget refusal, inspect the declared input, review and output limits before selecting another bounded run. Do not interpret partial work or elapsed process time as successful acceptance. If cleanup is incomplete, inspect the reported retained artifacts before retrying into a new destination. Existing files are not permission to overwrite or resume a failed publication.
GigaChat Advice Failed¶
Check the fixed local category first: missing extra, authentication, scope, TLS/CA bundle, rate limit, timeout, filtered response, invalid response, or unavailable service. Remote response bodies and SDK exception text are intentionally suppressed because they may reflect credentials or request metadata.
Configure exactly one of GIGACHAT_CREDENTIALS and
GIGACHAT_ACCESS_TOKEN. Match GIGACHAT_SCOPE to the API project, keep TLS
verification enabled, and use GIGACHAT_CA_BUNDLE_FILE only for a reviewed
readable CA bundle. Do not work around a certificate failure with an insecure
SDK example. A failed provider call leaves the workspace awaiting review and
does not create generated rows; retry only after correcting the local cause.
GigaChat's structured-output feature is currently beta. The adapter performs a
single local baseline-compatibility pass only after initial structured
validation fails, then reruns every normal validation. If invalid response
persists, the remaining provider proposal is not safe to review; use another
supported model or retry later instead of weakening validation.
Command Not Found¶
Symptom:
test-data-agent: command not found
Activate the environment where the package was installed:
source .venv/bin/activate
python3 -m pip show agent-paranoid-android
On Windows PowerShell:
.venv\Scripts\Activate.ps1
python -m pip show agent-paranoid-android
Output Already Exists¶
Folder workflows without overwrite support require a new or empty directory.
For example, choose a new path for generate-from-example:
test-data-agent generate-from-example data/example_dataset \
--count 25 \
--seed 12345 \
--format csv \
--output out/run-002
DatasetSpec generate --overwrite replaces the entire output folder, including
obsolete files, after generation and validation. Review the destination first;
see folder replacement and rollback.
Single-entity file bundles use separate ownership checks. A different primary filename or format, invalid or missing manifest, stale sidecar, or unrelated sibling is rejected before replacement. Use a new output folder instead of deleting evidence from an incomplete or mixed file bundle. Never point output at a source file or source folder.
Missing Optional Dependency¶
Optional commands print a version-pinned installation command and exit 69.
Run that command in the same environment as test-data-agent, then verify the
capability locally:
python -m pip install "agent-paranoid-android[postgres]==PACKAGE_VERSION"
test-data-agent doctor --require-extra postgres
Replace the extra and version with the exact values from the error. A passing local doctor check does not verify credentials or contact a remote service.
Malformed Input Or Unexpected Traceback¶
Malformed YAML/JSON and invalid models are normal input failures: they exit
2, publish no success artifact, and do not show a traceback. Use --json in
automation to branch on error.code.
Unexpected internal failures exit 70 with a fixed bounded message. Retry
with --debug only in a trusted terminal where technical paths and exception
context are safe to display. Provider response bodies and credentials remain
redacted even in normal provider errors.
Cancelled Operation¶
Ctrl+C exits 130 after catchable staging cleanup or bundle rollback. The
message confirms that no successful final bundle was published. Inspect an
agent workspace with agent-status; for a non-agent command, keep any
unexpected destination for investigation and retry into a new path.
Agent Approval Was Interrupted¶
Inspect the workspace:
test-data-agent agent-status out/agent
When it reports recovery_required, run the exact agent-recover command it
prints. Recovery requires the previously reviewed DatasetSpec SHA-256,
revalidates the existing generated bundle, and does not generate new rows.
Do not edit files under generated/ before recovery. A changed checkpoint,
manifest, report, spec, profile, or row file causes recovery to fail closed.
Process Or Host Stopped During Publication¶
For an agent workspace, run agent-status first. Use agent-recover only when
the status reports recovery_required; it revalidates the existing generated
bundle before publishing missing completion metadata.
For a non-agent generation command, do not treat a hidden staging directory or a destination without its expected manifest and validation report as success. Confirm that no generation process is still running, retain the incomplete files for investigation when needed, and rerun with the same reviewed inputs and seed into a new destination.
Where an atomic state writer or staged bundle publication is used, replacement
prevents readers from observing its partial state during normal operation.
Standalone artifact commands are not one global transaction. Shared atomic
single-file writes and owned directory publication use fsync, but complete
multi-file crash consistency is not guaranteed. A hard process stop, host or
storage failure, or power loss can still leave staging data or an incomplete
bundle. Use storage with the durability and backup
guarantees required by the deployment.
Input Limit Exceeded¶
The error names the failed limit. Prefer splitting an oversized source or reducing requested rows before raising the corresponding environment variable.
When a limit must change, set the smallest value that supports the reviewed workload and keep output and wall-clock limits in proportion.
See Configuration.
Sensitive Value Rejected¶
Profiles and business rules reject values that resemble PII, credentials, tokens, or private keys.
Do not bypass the detector by encoding or fragmenting a production value. Replace it with a semantic rule, a reserved example value, or a generator strategy.
Validation Failed¶
Open:
validation_report.json;business_validation_report.json, when present;- the effective spec and rule file.
Check the first failing section before changing generation settings. Common causes are an incorrect inferred relationship, impossible field ranges, conflicting formulas, and a business rule that references the wrong field.
Negative and mixed modes can fail validation intentionally. Keep their output separate and label it as invalid test data.
Results Are Not Reproducible¶
Confirm that both runs use the same:
- package version;
DatasetSpecand its fingerprint;- business-rule file and fingerprint;
- seed;
- row count, mode, invalid ratio, and format.
File ordering and output encoding should also be compared on the same supported platform.
Trino Allowlists Are Required¶
Set both variables:
export TRINO_ALLOWED_CATALOGS=hive,iceberg
export TRINO_ALLOWED_SCHEMAS=test_data,staging
Do not use TRINO_ALLOW_UNRESTRICTED=true merely to silence configuration
errors.
Plain HTTP Is Disabled¶
Use HTTPS for remote Trino. For an isolated local integration instance only:
export TRINO_HTTP_SCHEME=http
export TRINO_ALLOW_INSECURE_HTTP=true
MCP Path Rejected¶
Move the input or output below TEST_DATA_AGENT_WORKSPACE_ROOT. A textual path
that appears to be inside the workspace can still be rejected when an existing
symlink resolves outside it.
Use a real directory with no symlink boundary and request a new output path.
Reporting A Security Problem¶
Do not open a public issue containing exploit details, source data, PII, or credentials. Follow the repository security policy.
Known Issues¶
English · Русский
Stable 1.6.0 completed public verification.
External acceptance feedback was reconciled against current main on 2026-10-22;
the feedback work plan
separates historical fixes, current limitations and unverified observations.
- CSV numeric strings can remain phone-like and sensitive. Do not bypass privacy
checks or switch exact measures to float to suppress an error; reviewed numeric
profiling is planned. Exact decimal generation keeps its existing reviewed
--decimal-fieldscontract. - Trino already supports explicit runtime authentication over verified HTTPS. The external authentication failure still needs configuration/version evidence; fake-driver tests do not establish acceptance against a particular server.
- Numeric shape supports optional zero/subunit frequencies and a minimum subunit exponent. Older profiles can omit that evidence; reprofile before assuming it exists. A negative exponent is valid for values below one. Parquet distinct counts can be unavailable; missing statistics do not mean zero distinct values.
- Relationship validation checks declared relationships. Missing logical edges, source orphan rates and temporal granularity are not established by a passing validation report. Use reviewed declarations and explicit entity row counts.
These are development follow-ups, not changes already published in 1.6.0.
The separate transformation/session acceptance campaign remains open, including genuine local-terminal preservation acceptance where required. Existing automated and historical RC results do not establish its completion or private-data suitability. Provider adapters remain experimental; resource and artifact durability limits remain in their respective guides.
Resolved findings and their original risk dispositions are retained in Historical Security Findings.
Русский
Начало
Agent Paranoid Android¶
English · Русский
Agent Paranoid Android создаёт воспроизводимые синтетические тестовые данные по структуре CSV, безопасному профилю или проверенному DatasetSpec. Он нужен, когда важны схема, связи и бизнес-правила, а исходные строки нельзя передавать разработчикам.
Рекомендуемая стабильная версия — 1.6.0. Её исходники, пакеты и контейнеры прошли публичную проверку. Версия сохраняет принятый runtime RC5. Перед обновлением фикстур прочитайте изменения контракта.
С чего начать¶
| У вас есть | Откройте |
|---|---|
| Один CSV | Первый набор CSV |
| Папка связанных CSV | Связанные таблицы |
| PostgreSQL | Профилирование PostgreSQL |
| Trino | Профилирование через Trino |
| Безопасный профиль или DatasetSpec | Профили и спецификации |
Для первого знакомства: установка и встроенное демо. Демо не требует базы, AI или копии репозитория. Примерам с examples/ нужен checkout версии 1.6.0.
Основной процесс¶
- Получите структуру и ограниченные агрегаты.
- Проверьте DatasetSpec, связи и бизнес-правила.
- Создайте новые значения с явным seed.
- Проверьте типы, связи, ограничения, приватность и бизнес-правила.
- Прочитайте generation_manifest.json перед принятием набора.
Manifest синтетического набора содержит synthetic=true, source_rows_copied=false, seed и validation_valid. Эти поля не заменяют проверку самого spec и не подтверждают статистическую анонимность.
Интеграции¶
AI, MCP, контейнеры и собственный provider — English — отдельные возможности. Для обычной генерации они не обязательны.
Границы безопасности¶
Генерация не копирует и не перемешивает исходные строки. Внешние базы читаются только в разрешённом scope, с конечными бюджетами. Ограниченное локальное разрешение business enum не распространяется на идентификаторы, свободный текст, PII или provider payload.
Конечная fictional acceptance campaign 1.6.0 завершена с записанными ограничениями; это не одобрение пользовательского набора. Selective transformation — отдельная opt-in операция со смешанным происхождением результата. Она не является синтетической генерацией. Сохранение ячеек требует local receipt от человека; регистрация CLI/MCP не одобряет набор. См. workflow и модель безопасности.
Языковые версии¶
Это русская редакция существующих пользовательских разделов: пути после ru/ соответствуют английским страницам. Переключатель English / Русский открывает соответствующую страницу; ссылки доступны и при чтении Markdown в репозитории. Техническая справка --help, имена API и ключи остаются в оригинале.
Исторические release evidence, ADR и служебные записи сопровождающих доступны в оригинале и помечены English. Они не представлены как переведённые страницы. Проверенные локальные примеры перенесены из прежнего русского руководства без изменения команд; условия и ограничения приведены в отчёте.
Установка¶
English · Русский
Рекомендуемая стабильная версия — 1.6.0; см. публичную проверку. Нужны Python 3.11+, место для результата и отдельная рабочая папка. CI поддерживает CPython 3.11–3.14; этот локальный аудит выполнен на macOS с Python 3.11.2.
Установка из PyPI¶
На macOS/Linux откройте терминал в выбранной рабочей папке и выполните по очереди:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install "agent-paranoid-android==1.6.0"
test-data-agent --version
test-data-agent doctor
Ожидается версия 1.6.0 и doctor passed. Если команда не найдена, активируйте окружение и проверьте путь команды. Doctor использует временную вымышленную фикстуру и не обращается к внешним сервисам. Ошибка TLS при установке требует исправления сертификатов/индекса, а не отключения проверки.
Установка из индекса и загрузка зависимостей не проверялись выполнением этим аудитом. Локальный wheel 1.6.0 и доступные зависимости проверены отдельно; это не доказательство чистой PyPI installation.
Windows PowerShell¶
Откройте PowerShell в рабочей папке; не используйте Bash activation. Отдельный маршрут без изменения ExecutionPolicy:
py -3.11 -m venv .venv
.\.venv\Scripts\python.exe -m pip install "agent-paranoid-android==1.6.0"
.\.venv\Scripts\test-data-agent.exe --version
.\.venv\Scripts\test-data-agent.exe doctor
Ожидается 1.6.0 и doctor passed. При отсутствии launcher установите поддерживаемый Python. Windows-выполнение здесь не проверено. В следующих инструкциях заменяйте python и test-data-agent этими путями; вводите Bash-команды с продолжением строки одной строкой.
Необязательные extras¶
Base поддерживает CSV, JSON и SQL export. Устанавливайте нужный extra с тем же точным pin: например, python -m pip install "agent-paranoid-android[parquet]==1.6.0". Доступны parquet, mcp, trino, postgres, openai и gigachat; all предназначен для разработки/демо/контейнеров.
Проверьте extra локально через test-data-agent doctor --require-extra parquet, заменив имя. Это не проверка сети, credentials или подключения БД/provider. GigaChat и OpenAI adapters остаются experimental. См. поддержку и footprint — English.
Когда нужна копия репозитория¶
Демо ниже работает без Git. Примеры с examples/ требуют checkout 1.6.0, например отдельный clone тега v1.6.0. Не переключайте изменённую или старую рабочую копию автоматически. Разработка описана в Contributing, сборка сайта — в Publishing Documentation — English.
Перед обновлением существующих фикстур прочитайте миграцию. Package version и DatasetSpec schema_version различаются.
Первый запуск без собственных данных¶
Для чего это нужно¶
Демонстрация проверяет весь базовый путь на встроенной вымышленной таблице. Она не требует клонирования репозитория, базы данных или AI.
Что получится в результате¶
Новая папка out/ru-demo с 12 синтетическими покупателями и проверочными артефактами.
Предварительные требования¶
Установка завершена. Откройте терминал в выбранной рабочей папке, активируйте окружение; убедитесь, что out/ru-demo ещё не существует.
Пошаговое выполнение¶
Шаг 1. Запустите демонстрацию¶
Что сделать: Создайте набор из встроенной фикстуры.
Где выполнить: Терминал, рабочая папка.
Команда или пример:
test-data-agent demo --output out/ru-demo
Что должно произойти: Генератор создаёт customers.csv, csv_profile.json, dataset_spec.json, validation_report.json и generation_manifest.json.
Как проверить: Команда завершилась кодом 0; вывод содержит validation: passed.
Если не получилось: При существующей папке выберите out/ru-demo-2. При недоступной команде вернитесь к установке.
Шаг 2. Проверьте manifest¶
Что сделать: Проверьте флаги и фиксированный seed демо, не печатая строки.
Где выполнить: Тот же каталог.
Команда или пример:
python -c "import json; from pathlib import Path; m=json.loads(Path('out/ru-demo/generation_manifest.json').read_text()); assert m['synthetic'] is True and m['source_rows_copied'] is False and m['validation_valid'] is True and m['seed']==20260801; print('demo: ok')"
Что должно произойти: Печатается demo: ok.
Как проверить: Все assert выполнены.
Если не получилось: При отсутствующем файле проверьте путь и предыдущую ошибку. При неверном флаге остановитесь и не используйте набор.
Проверка результата¶
Откройте validation_report.json: valid должен быть true. В customers.csv должно быть 12 строк данных плюс заголовок. Демо не подтверждает сохранение связей и бизнес-правил: в его входе нет таких свидетельств.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
unsafe filesystem path |
Путь содержит запрещённый компонент или symlink | Используйте обычную новую папку внутри рабочей папки. На macOS /tmp может вести в /private/tmp. |
output уже существует (точный текст зависит от операции) |
Защита от перезаписи | Выберите новое имя папки. |
Следующий шаг¶
Первый набор CSV¶
English · Русский
Для чего это нужно¶
Пример показывает отдельные этапы профилирования, построения спецификации, генерации и повторной проверки. Он подходит для знакомства; для своего чувствительного источника сначала используйте процесс с ручным review.
Что получится в результате¶
Профиль, DatasetSpec, 25 новых покупателей и два отчёта валидации.
Предварительные требования¶
Установлен Python 3.11+ и пакет проекта. Терминал открыт в корне репозитория agent-paranoid-android; виртуальное окружение активно. Входы — только вымышленные файлы из репозитория. Папка назначения новая; есть права чтения входов и записи результата. Для команд ниже используйте macOS/Linux; в PowerShell вводите каждую команду одной строкой без \.
Пошаговое выполнение¶
Шаг 1. Выполните готовый пример¶
Что сделать: Запустите существующий сценарий с отдельной новой папкой.
Где выполнить: macOS/Linux, корень checkout.
Команда или пример:
bash examples/csv_quickstart/run.sh out/ru-quickstart
Что должно произойти: Последовательно выполняются profile-csv, infer-spec, generate и validate.
Как проверить: В out/ru-quickstart/generated есть customers.csv, manifest и validation_report.json.
Если не получилось: Если test-data-agent не найден, активируйте окружение. Если папка занята, выберите новое имя.
Шаг 2. Проверьте результат¶
Что сделать: Прочитайте повторный отчёт автоматически.
Где выполнить: Тот же каталог.
Команда или пример:
python -c "import json; from pathlib import Path; r=json.loads(Path('out/ru-quickstart/revalidation_report.json').read_text()); assert r['valid'] is True; print('validation: ok')"
Что должно произойти: Проверка прошла без вывода строк данных.
Как проверить: Код 0 и validation: ok.
Если не получилось: Если valid=false, проверьте секции отчёта и используйте раздел диагностики.
Проверка результата¶
Сопоставьте имена и типы полей в dataset_spec.yaml с ожидаемыми. Прочитайте generation_manifest.json. Скрипт на вымышленном входе выполняет все этапы подряд; на новом реальном домене остановитесь после infer-spec для review.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
Output already exists: |
Скрипт не перезаписывает результаты | Задайте новую выходную папку. |
command not found |
Нет активного окружения | Вернитесь к установке. |
На Windows этот Bash-скрипт не является проверенным способом запуска. Выполните отдельные команды из основного процесса в PowerShell, каждую одной строкой.
Следующий шаг¶
Сгенерировать одну таблицу CSV¶
Для чего это нужно¶
Сокращённая команда подходит для известной структуры и небольшого проверенного входа. Она сразу профилирует CSV и создаёт DatasetSpec, данные и отчёты; для нового чувствительного домена используйте отдельный review.
Что получится в результате¶
В out/ru-csv будут customers.csv (25 строк), csv_profile.json, dataset_spec.json, validation_report.json и generation_manifest.json.
Предварительные требования¶
Установлен Python 3.11+ и пакет проекта. Терминал открыт в корне репозитория agent-paranoid-android; виртуальное окружение активно. Входы — только вымышленные файлы из репозитория. Папка назначения новая; есть права чтения входов и записи результата. Для команд ниже используйте macOS/Linux; в PowerShell вводите каждую команду одной строкой без \.
Пошаговое выполнение¶
Шаг 1. Сгенерируйте 25 строк¶
Что сделать: Используйте существующую вымышленную фикстуру и явные параметры.
Где выполнить: Корень checkout.
Команда или пример:
test-data-agent generate-from-csv examples/csv_quickstart/customers.csv --count 25 --seed 12345 --format csv --output out/ru-csv/customers.csv
Что должно произойти: Создан один файл данных и соседние артефакты.
Как проверить: Команда сообщает validation: passed; создан manifest.
Если не получилось: Убедитесь, что --output задаёт файл, а не папку. Для повтора выберите новую папку.
Шаг 2. Проверьте manifest и число строк¶
Что сделать: Проверьте флаги без печати содержимого CSV.
Где выполнить: Корень checkout.
Команда или пример:
python -c "import json; from pathlib import Path; p=Path('out/ru-csv'); m=json.loads((p/'generation_manifest.json').read_text()); assert m['synthetic'] is True and m['source_rows_copied'] is False and m['validation_valid'] is True and m['seed']==12345; print('manifest: ok')"
python -c "import csv; from pathlib import Path; f=Path('out/ru-csv/customers.csv').open(newline=''); assert len(list(csv.DictReader(f)))==25; print('rows: ok')"
Что должно произойти: Печатаются manifest: ok и rows: ok.
Как проверить: Обе команды завершаются кодом 0.
Если не получилось: Если строки не совпали, не используйте результат; сохраните отчёт и запустите validate.
Шаг 3. Повторите с тем же seed¶
Что сделать: Создайте отдельный набор для проверки воспроизводимости.
Где выполнить: Тот же checkout и окружение.
Команда или пример:
test-data-agent generate-from-csv examples/csv_quickstart/customers.csv --count 25 --seed 12345 --format csv --output out/ru-csv-repeat/customers.csv
Что должно произойти: Создан второй CSV при тех же входах и настройках.
Как проверить: Оба файла можно сравнить командой ниже.
Если не получилось: Не изменяйте CSV и зависимости между запусками.
Что сделать: Сравните байты CSV в одном окружении.
Где выполнить: Корень checkout.
Команда или пример:
python -c "from pathlib import Path; assert Path('out/ru-csv/customers.csv').read_bytes()==Path('out/ru-csv-repeat/customers.csv').read_bytes(); print('deterministic: ok')"
Что должно произойти: Файлы совпадают.
Как проверить: Код 0.
Если не получилось: Проверьте вход, seed, count, locale и версии зависимостей; manifest может содержать сведения окружения, поэтому не сравнивайте все артефакты как один файл.
Проверка результата¶
Выполните test-data-agent validate out/ru-csv/dataset_spec.json out/ru-csv. Ожидается код 0. Для своего входа замените путь CSV, сохраните заголовок и отдельный выходной каталог; не вставляйте его строки в чат.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
| Ошибка разбора CSV (текст зависит от входа) | Кодировка, разделитель или повреждённый заголовок | Подготовьте небольшой синтетический аналог и проверьте его локально; не публикуйте исходные строки. |
unsafe filesystem path |
Вход и выход конфликтуют или путь содержит symlink | Разнесите вход и результат по обычным папкам. |
Что важно про значения¶
Одинаковый seed гарантирует повтор в зафиксированном окружении, а не между любыми версиями Faker, сериализаторов и платформ. Сохраните spec, seed и manifest.
По умолчанию исходные категории заменяются. --local-category customers.status — отдельное разрешение на проверенный ограниченный нечувствительный enum, а не способ сохранить идентификаторы или текст. Не включайте его без review содержимого и назначения. CSV-политика ограничивает такие строковые enum 20 значениями длиной до 64 символов. Чувствительные значения всё равно отклоняются. В этом руководстве разрешение не используется.
Следующий шаг¶
Проверить результат¶
English · Русский
Для чего это нужно¶
Валидация сверяет данные с DatasetSpec; manifest помогает восстановить условия генерации. Это обязательные технические проверки перед использованием фикстуры, но предметную полезность оценивает человек.
Что получится в результате¶
Повторный отчёт valid=true и подтверждённое число строк.
Предварительные требования¶
Выполните CSV-генерацию, не изменяйте её spec и файлы. Команды выполняйте в корне того же checkout.
Пошаговое выполнение¶
Шаг 1. Выполните повторную валидацию¶
Что сделать: Создайте отдельный отчёт, сохранив первоначальный.
Где выполнить: Терминал, корень checkout.
Команда или пример:
test-data-agent validate out/ru-csv/dataset_spec.json out/ru-csv --output out/ru-csv-revalidation.json
Что должно произойти: Сверены типы, связи, ограничения и privacy.
Как проверить: Код 0, valid=true в новом JSON.
Если не получилось: Код 1 означает нарушение; прочитайте errors. Код 2 означает ошибку входов/параметров.
Шаг 2. Прочитайте итоговые флаги¶
Что сделать: Проверьте manifest автоматически.
Где выполнить: Тот же терминал.
Команда или пример:
python -c "import json; from pathlib import Path; p=Path('out/ru-csv'); m=json.loads((p/'generation_manifest.json').read_text()); assert m['synthetic'] is True and m['source_rows_copied'] is False and m['validation_valid'] is True and m['seed']==12345; print('manifest: ok')"
Что должно произойти: Флаги прошли проверку.
Как проверить: Код 0.
Если не получилось: При false или отсутствующем поле остановите передачу набора и проверьте версию артефакта.
Проверка результата¶
Проверьте, что в отчёте включены schema, relationships, constraints, privacy. Не считайте отсутствие секции успешной проверкой. Дополнительно оцените нужные диапазоны, null, распределения и полноту правил для вашей задачи. При business-rules прочитайте также business_validation_report.json: validate использует embedded business_rules или явно переданный --business-rules и не изменяет проверяемые строки. Сверьте также отдельный бизнес-отчёт.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
| Код 1 | Данные не соответствуют spec | Прочитайте ошибки секций; проверьте, что spec именно от этого набора. |
| valid=true, но нужного свойства нет | Свойство не формализовано или проверка отключена | Добавьте проверяемое правило; включите соответствующую validation_settings. |
Как читать артефакты¶
| Артефакт | Что проверять |
|---|---|
| csv_profile.json / profile.json | Сущности, типы, чувствительность, границы наблюдений |
| dataset_spec.json / dataset_spec.yaml | Итоговый контракт; счётчики, поля, ключи, правила |
| validation_report.json | valid, включённые секции, errors |
| generation_manifest.json | seed, синтетичность, отсутствие копирования строк, результаты проверок, окружение |
| business_validation_report.json | При правилах: valid и ожидаемые/наблюдаемые нарушения |
mixed и negative могут намеренно создавать ошибки. Для них проверяют expectations_met, unexpected_violation_count, missing_expected_violation_count, а не требуют обычное valid=true. В valid ожидается отсутствие нарушений. В 1.6.0 при неуспешной валидации generate возвращает exit code 1 / JSON status validation_failed даже для mixed/negative, сохраняя намеренно неверные артефакты и отчёты. Код 1 не означает rollback. Приватность остаётся обязательной: её нарушение блокирует публикацию.
Следующий шаг¶
Выбрать формат результата¶
Для чего это нужно¶
Выберите формат, который принимает ваша тестовая система. Генерируемые файлы содержат новые строки; экспорт SQL не читает и не выгружает исходные строки.
Что получится в результате¶
CSV, JSON, SQL, Parquet и отдельный PostgreSQL DDL+INSERT из одного spec.
Предварительные требования¶
Установлен Python 3.11+ и пакет проекта. Терминал открыт в корне репозитория agent-paranoid-android; виртуальное окружение активно. Входы — только вымышленные файлы из репозитория. Папка назначения новая; есть права чтения входов и записи результата. Для команд ниже используйте macOS/Linux; в PowerShell вводите каждую команду одной строкой без \. Дополнительно установлен extra parquet; Bash для готового скрипта.
Пошаговое выполнение¶
Шаг 1. Сгенерируйте все форматы¶
Что сделать: Запустите существующий сценарий форматов.
Где выполнить: macOS/Linux, корень checkout.
Команда или пример:
bash examples/output_formats/run.sh out/ru-formats
Что должно произойти: Созданы подпапки csv, json, sql, parquet и postgres.sql.
Как проверить: В каждой подпапке есть manifest и validation_report.json.
Если не получилось: Если PyArrow отсутствует, установите .[parquet] в активное окружение; повторите в новой папке.
Шаг 2. Проверьте доступные для чтения форматы¶
Что сделать: Повторите валидацию CSV, JSON, SQL и Parquet по тому же spec.
Где выполнить: Корень checkout.
Команда или пример:
test-data-agent validate examples/output_formats/dataset_spec.yaml out/ru-formats/csv
test-data-agent validate examples/output_formats/dataset_spec.yaml out/ru-formats/json
test-data-agent validate examples/output_formats/dataset_spec.yaml out/ru-formats/sql
test-data-agent validate examples/output_formats/dataset_spec.yaml out/ru-formats/parquet
Что должно произойти: Прочитаны экспортированные данные.
Как проверить: Каждая команда возвращает 0.
Если не получилось: SQL-папка должна содержать именно сгенерированный INSERT bundle с manifest. Произвольный SQL и отдельный PostgreSQL DDL-файл не принимаются.
Проверка результата¶
В manifest каждого набора проверьте synthetic=true, source_rows_copied=false и validation_valid=true. SQL здесь только сформирован; его исполнение на сервере в этом аудите не проверялось.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
| Отсутствует pyarrow / missing_dependency | Не установлен extra parquet | Установите .[parquet] и проверьте doctor --require-extra parquet. |
| SQL не читается validate | Передан произвольный SQL или DDL export | Передайте папку с созданным проектом INSERT bundle и manifest; validate не выполняет SQL. |
Физическое представление в 1.6.0¶
CSV bundle объявляет в manifest csv_encoding: backslash-null-v1: \N — null, пустая ячейка — пустая строка, начальный обратный слеш удваивается. Формулы и опасные для spreadsheet строки/заголовки экранируются \F. Сохраняйте manifest вместе с CSV для обратимого чтения; не применяйте это декодирование к старым немаркированным CSV.
DECIMAL хранится точной строкой в CSV/JSON и decimal128 в Parquet. Для широких integer, смешанных timezone offsets и malformed negative cells Parquet может использовать маркированные строковые представления; при прямом чтении проверяйте apa.scalar_encoding или используйте bundle reader. Native decode одного Arrow batch предшествует проверке payload: лимит expanded bytes не гарантирует верхнюю границу памяти процесса.
В 1.6.0 validate читает ограниченную грамматику созданных INSERT bundles без исполнения SQL и без подключения к БД. DDL, функции, комментарии и произвольные SQL-скрипты этим не разрешаются.
Различия форматов¶
| Формат | Файлы | Ограничения |
|---|---|---|
| csv | <entity>.csv |
Текстовое представление; типы задаются spec |
| json | <entity>.json |
Строки сущности в JSON |
| parquet | <entity>.parquet |
Нужен PyArrow; отдельное optional extra |
| sql | <entity>.sql |
Кавычки и INSERT; без CREATE TABLE |
| export-postgres-sql | Один .sql |
Транзакция, CREATE TABLE, FK и INSERT; PostgreSQL |
Для одного формата выполните test-data-agent generate examples/output_formats/dataset_spec.yaml --seed 271828 --format csv --output out/ru-one-format. Команда сверена с parser; эквивалентный вызов исполняется скриптом выше.
export-postgres-sql создаёт файл, но не подключается к целевой БД. Сам файл содержит операции записи. Перед его исполнением человек должен проверить целевой сервер, базу, роли и SQL; используйте отдельную пустую тестовую БД. Создание файла не является разрешением на его исполнение.
Следующий шаг¶
Инструкции
Генерация с бизнес-правилами¶
English · Русский
Для чего это нужно¶
Задайте правила YAML/JSON, когда одной схемы недостаточно: например amount=quantity*unit_price, порядок дат или обязательное поле. Детерминированный код применяет и проверяет правила; текстовое обещание AI не заменяет правило.
Что получится в результате¶
Две синтетические таблицы и business_validation_report.json.
Предварительные требования¶
Установлен Python 3.11+ и пакет проекта. Терминал открыт в корне репозитория agent-paranoid-android; виртуальное окружение активно. Входы — только вымышленные файлы из репозитория. Папка назначения новая; есть права чтения входов и записи результата. Для команд ниже используйте macOS/Linux; в PowerShell вводите каждую команду одной строкой без \. Для этого сценария достаточно базового пакета.
Пошаговое выполнение¶
Шаг 1. Изучите правила примера¶
Что сделать: Откройте rules.yaml; проверьте ссылки на таблицы и поля.
Где выполнить: Редактор, examples/relational_csv/rules.yaml.
Команда или пример:
examples/relational_csv/rules.yaml
Что должно произойти: Видны структурированные правила вымышленного домена.
Как проверить: Имена совпадают с CSV и будущим spec; чувствительных литералов нет.
Если не получилось: Не переносите правила с реальными ID, адресами или секретами. Формула — ограниченная арифметика, не Python.
Шаг 2. Выполните связанный пример¶
Что сделать: Запустите профиль → spec → generate с правилами → validate.
Где выполнить: macOS/Linux, корень checkout.
Команда или пример:
bash examples/relational_csv/run.sh out/ru-rules
Что должно произойти: Созданы customers.csv, orders.csv, validation_report.json, business_validation_report.json и manifest.
Как проверить: Команды завершаются успешно; manifest содержит business_validation.
Если не получилось: При противоречии правил и spec исправьте имена и требования; не удаляйте проверки ради успешного отчёта.
Шаг 3. Проверьте бизнес-отчёт¶
Что сделать: Проверьте valid без печати строк.
Где выполнить: Корень checkout.
Команда или пример:
python -c "import json; from pathlib import Path; r=json.loads(Path('out/ru-rules/generated/business_validation_report.json').read_text()); assert r['valid'] is True; print('business rules: ok')"
Что должно произойти: Правила выполнены.
Как проверить: Код 0.
Если не получилось: При нарушении прочитайте счётчики правил; обычный schema valid не означает успешные business rules.
Проверка результата¶
Сверьте rule fingerprint и счётчики в manifest с выбранным файлом. Нужные бизнес-инварианты должны быть явно представлены и проверены. Отсутствующее правило не проверяется автоматически.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
| Неизвестный тип/поле правила | Опечатка или неподдерживаемая конструкция | Сопоставьте правило с spec и справочником правил. |
| Превышен work budget | Слишком много строк × правил | Уменьшите тест; меняйте лимиты только после оценки ресурсов. |
Переносимость и смысл правил в 1.6.0¶
DatasetSpec.business_rules переносит правила между Python, CLI, MCP, agent workspace и всеми форматами. infer-spec --business-rules сохраняет их в spec; generate, validate и export-postgres-sql также принимают отдельный --business-rules. Повторная валидация проверяет данные и не присваивает значения заново.
У формул mode: assign по умолчанию задаёт результат; mode: check только проверяет. Отчёт содержит application и assigned_row_count: зелёный результат после присваивания не доказывает независимую верность бизнес-гипотезы. Поддерживаются явные equals: null / not_equals: null и числовые включительные gte/lte. DECIMAL-формулы и aggregate mappings используют точную арифметику с однократным HALF_UP округлением в scale целевого поля. Подробности: контракт правил 1.6.
Категории и ограничения¶
Поддерживаются field rules (required, allowed values, bounds), conditional required/allowed values, temporal ordering, formula, foreign key, aggregate formula и weighted scenario. Не все агрегатные правила могут создавать отрицательные данные: count с field: "*" — только проверка, поскольку изменение числа строк нарушило бы форму набора.
Пример контролируемых нарушений, проверенный существующими документационными тестами:
test-data-agent generate examples/negative_cases/dataset_spec.yaml --seed 1300 --mode mixed --invalid-ratio 0.5 --format json --business-rules examples/negative_cases/business_rules.yaml --output out/ru-negative
При намеренных нарушениях команда 1.6.0 возвращает exit code 1, хотя набор и validation evidence сохранены. Это ожидаемое поведение данного negative-примера. Держите такой набор отдельно. Успех отрицательного сценария — совпадение ожидаемых и наблюдаемых нарушений (expectations_met=true, ноль unexpected и missing expected), а не отсутствие нарушений. Режим negative и mixed не разрешает PII. Точные поля правил и примеры всех категорий описаны в существующем руководстве.
Следующий шаг¶
Условные формулы и синтетическая EAV-модель¶
Формула в режиме assign или check принимает необязательное условие when.
При ложном условии выражение не вычисляется, значение не меняется, строка
считается пропущенной. Отчёт отдельно возвращает eligible_row_count,
evaluated_row_count и skipped_row_count; пропуск не считается успехом.
Правила без when сохраняют прежние отпечатки и поведение. equals: null
выбирает пустое или отсутствующее значение; числовой диапазон его не выбирает.
Неизвестное в DatasetSpec поле условия отклоняется до генерации.
Поле условия нельзя изменять другими построчными правилами. Несколько формул
назначения одного поля разрешены для доказуемо непересекающихся equals или
in_values по одному полю. Пересечение, диапазон или недоказанная совместимость
отклоняются. Проверки чувствительных литералов, точная арифметика DECIMAL,
общий лимит работы и срок выполнения остаются обязательными.
Исполняемый пример EAV
использует заранее заданные синтетические атрибуты ratio и total, независимые
идентификаторы и две условные формулы. Одна запись содержит один атрибут и одно
значение. Отсутствие наблюдения отличается от пустого значения. Уникальность
пары сущность/атрибут нужно объявить отдельно; пример допускает повторение.
Преобразование исходных строк, сохранение ключей и разрешение дубликатов
источника этим примером не выполняются.
Профилирование PostgreSQL¶
English · Русский
Для чего это нужно¶
Используйте базу как источник разрешённых метаданных и агрегатов, когда CSV неудобен. Этот путь не предназначен для выгрузки строк или выполнения произвольного SQL.
Что получится в результате¶
Профиль PostgreSQL или Trino для последующего review DatasetSpec; исходная база не изменяется.
Предварительные требования¶
Не проверено выполнением на живой БД. Нужны соответствующие extras, сетевой доступ, TLS и уже созданная администратором read-only роль. Человек согласует точные сервер, БД, таблицы, поля, бюджеты и локальное место сохранения. Секрет вводится через runtime secret mechanism, не через Git или чат.
Пошаговое выполнение¶
Шаг 1. Настройте точный scope PostgreSQL¶
Что сделать: Замените вымышленные host/database/user на согласованные значения. Секрет WAREHOUSE_PASSWORD должен быть уже внедрён средой; не печатайте его.
Где выполнить: macOS/Linux, терминал в корне checkout; PowerShell требует собственного синтаксиса $env:.
Команда или пример:
export POSTGRES_SOURCE_ID=warehouse
export POSTGRES_HOST=db.example.internal
export POSTGRES_PORT=5432
export POSTGRES_DATABASE=analytics
export POSTGRES_USER=synthetic_reader
export POSTGRES_SSLMODE=verify-full
export POSTGRES_PASSWORD_ENV=WAREHOUSE_PASSWORD
export POSTGRES_ALLOWED_SCHEMAS=public
export POSTGRES_ALLOWED_TABLES=public.orders
export POSTGRES_ALLOWED_COLUMNS=public.orders.order_id,public.orders.amount
Что должно произойти: Scope ограничен одной таблицей и двумя полями.
Как проверить: Локально: test-data-agent doctor --require-extra postgres. Администратор отдельно подтверждает SELECT-only права и цепочку сертификатов.
Если не получилось: Doctor не проверяет БД. При недоступности сертификата или секрета остановитесь; не отключайте TLS.
Шаг 2. Получите безопасный профиль¶
Что сделать: После согласования выполните ограниченное чтение.
Где выполнить: Тот же терминал.
Команда или пример:
test-data-agent profile-postgres --output out/ru-postgres/profile.json
Что должно произойти: Создан агрегированный профиль без строк источника.
Как проверить: Код 0; entities содержит только согласованные поля.
Если не получилось: Используйте фиксированную категорию ошибки; не публикуйте driver output, DSN или secret. Проверьте allowlist и права с администратором.
Шаг 3. Создайте контракт для review¶
Что сделать: Выведите spec, затем откройте его локально.
Где выполнить: Корень checkout.
Команда или пример:
test-data-agent infer-spec out/ru-postgres/profile.json --count 25 --output out/ru-postgres/dataset_spec.yaml
Что должно произойти: Спецификация готова к проверке человеком.
Как проверить: Проверьте типы, sensitive, диапазоны и row_count; строки ещё не сгенерированы.
Если не получилось: Если метаданных недостаточно, уточните правило у владельца данных; не добавляйте sample rows.
Проверка результата¶
После review продолжите командой generate с явным seed в новой папке и validate из основного процесса. Read-only session — дополнительная защита; права самой роли должны исключать запись.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
| Ошибка конфигурации / код 2 | Отсутствует allowlist или конфликтуют компоненты URL | Проверьте scope; не включайте unrestricted-доступ. |
| external_service / код 69 | Сеть, TLS, аутентификация или доступ | Согласуйте с администратором; не передавайте исходное сообщение драйвера. |
Trino¶
Прямой команды profile-trino нет. Используйте Trino MCP profile_table_safe, а затем generator plan_trino_dataset, либо документированный Python API. Для воспроизводимого изолированного примера есть local_trino; он не запускался в этом аудите и требует своей инфраструктуры.
Минимальные согласованные настройки: TRINO_HOST, TRINO_PORT, TRINO_USER, TRINO_HTTP_SCHEME=https, TRINO_ALLOWED_CATALOGS, TRINO_ALLOWED_SCHEMAS, TRINO_ALLOWED_TABLE_COLUMNS. Укажите точные catalog.schema.table.column; задайте бюджеты из справочника. Для shared-hardened обязателен конечный TRINO_MAX_INVOCATION_ESTIMATED_SCAN_BYTES.
Профиль результата ограниченного запроса¶
profile-query принимает локальный UTF-8 файл с одним разрешённым single-table SELECT. Пример для scope выше, не проверен выполнением на БД:
SELECT o.order_id, o.amount
FROM public.orders AS o
WHERE o.order_id < 1000
Сохраните как query.sql в корне checkout. После локального review и разрешения на чтение выполните:
test-data-agent profile-query query.sql --adapter postgres --source-id warehouse --entity orders_query --output out/ru-query/profile.json
Для Trino используйте --adapter trino с полностью квалифицированной таблицей catalog.schema.table, явным allowlist полей и настроенным Trino-клиентом. JOIN, CTE/WITH, подзапросы и запись не поддерживаются; запрос проходит разбор AST (синтаксического дерева), затем только no-row schema probe и агрегатные обёртки. Результат содержит fingerprint, не SQL-текст, литералы или query rows. Профиль проверяют и передают infer-spec так же, как табличный профиль.
Endpoint можно задавать credential-free POSTGRES_JDBC_URL или TRINO_JDBC_URL; это не JDBC-исполнение. Wildcard schema.table.* / catalog.schema.table.* разрешает лишь ограниченное раскрытие столбцов через метаданные, не сохранение исходных категорий.
Подробности: PostgreSQL, Trino, SQL policy. Прямые нечувствительные date/timestamp projections могут получать проверенные temporal bounds; sensitive и derived поля их не получают. Declared numeric(p,s) несёт precision/scale, но не exact bounds: используйте reviewed decimal_range.
Следующий шаг¶
Зависимости SQL-выражений¶
Профиль запроса может помечать has_unmodeled_expressions=true. В этом случае автоматический infer-spec по умолчанию останавливается: независимая генерация столбцов не сохраняет SQL-формулы. Составьте независимо проверенный spec; публичного флага обхода для автоматического inference здесь нет. В SQL policy 1.1 разрешены aliased SUM/COUNT/MIN/MAX/AVG и ограниченный GROUP BY по явным столбцам одной таблицы; HAVING, DISTINCT aggregates и grouping expressions не поддерживаются. Такой профиль не доказывает сохранение SQL-зависимостей. Обычное агрегатное профилирование не смешивайте с отдельной configured_query_session capture-трансформацией.
Исправление primary key в текущем main¶
После 1.6.0 main распознаёт объявленный single-column integer или string primary key независимо от имени, например ticket_no/record_code. Identifiers создаются заново; sensitivity сохраняется. Чтобы получить эти metadata, сохранённый профиль нужно построить заново.
Composite primary key отклоняется до aggregate scans, даже если column allowlist открывает только один компонент. Он не превращается в ложный однопольный PK. Для других типов нужен независимо проверенный generation spec; automatic inference не поддерживает composite uniqueness.
Это описание текущего main, а не новое содержимое выпущенного wheel 1.6.0. Полный контракт: исходная инструкция — English.
Профилирование через Trino¶
English · Русский
Trino — отдельный read-only источник метаданных и агрегатов. В 1.6.0 сохранены JDBC-style endpoints без credentials, точные allowlists, ограниченные table-qualified wildcards и profile-query. Java и JDBC driver не нужны.
Перед запуском¶
Нужны extra trino, а для MCP — также mcp; проверенный HTTPS endpoint, read-only роль и явно согласованный catalog/schema/table/column scope. Секреты внедряются через runtime secret mechanism. Сетевое выполнение этого руководства не проверено.
Локальная проверка установки из активного окружения:
test-data-agent doctor --require-extra trino
Doctor проверяет клиент и SQL policy без обращения к координатору. Он не подтверждает аутентификацию или доступ к таблицам.
Настройте scope¶
Иллюстрация конфигурации для вымышленного endpoint; заменяйте её только согласованными параметрами:
export TRINO_HOST=trino.example.internal
export TRINO_PORT=8443
export TRINO_USER=test_data_agent
export TRINO_HTTP_SCHEME=https
export TRINO_ALLOWED_CATALOGS=warehouse
export TRINO_ALLOWED_SCHEMAS=analytics
export TRINO_ALLOWED_TABLE_COLUMNS='warehouse.analytics.orders.*'
export TRINO_DEPLOYMENT_PROFILE=shared-hardened
export TRINO_MAX_INVOCATION_ESTIMATED_SCAN_BYTES=1073741824
Catalog и schema — независимые allowlist-множества. Wildcard разрешён только для точной таблицы в restricted mode: ограниченные metadata разворачиваются в отсортированные явные столбцы до первого агрегата. Он не разрешает SQL *, literals, preserve или provider payload. Column selectors не являются общим ACL всех MCP tools; ограничения видимости задаются также правами БД.
Вместо компонентов endpoint допускается TRINO_JDBC_URL без credentials. Явные компоненты должны совпадать с URL. SSL=false, неизвестные свойства, токены, роли, proxies и headers в URL отклоняются. Basic/JWT/Kerberos/GSSAPI/OAuth2 и client certificates требуют своих настроек; см. оригинальный полный справочник подключения.
Получите профиль¶
MCP server запускается локальным клиентом через test-data-agent-mcp-trino. Default aggregate-only tools возвращают разрешённые metadata и агрегаты. Затем безопасный профиль передаётся generator plan_trino_dataset без исходных строк; spec проверяется до генерации. См. MCP.
Отдельный explicit opt-in run_safe_select по умолчанию отсутствует. Его ограниченные строки могут содержать исходные нестроковые значения; маскирование не делает их анонимными. Эти строки не передаются генератору или LLM.
Воспроизводимый инфраструктурный пример¶
В репозитории есть examples/local_trino/run.sh и варианты run-jdbc.sh, run-wildcard.sh, run-query.sh. Они используют синтетический TPC-H tiny в одноразовом контейнере, удаляют контейнер и сохраняют безопасный профиль, spec, новые данные и отчёты. В этом аудите инфраструктурные сценарии не запускались.
Query-source требует явного column scope, хранит fingerprint вместо текста SQL и результатов. Не обходите отказ через unrestricted/insecure flags. Успех проверяется по scope, коду завершения, профилю без строк и отчётам сгенерированного набора; ошибка авторизации требует исправления grants или сужения запроса.
MCP с логином и паролем¶
Для входа по логину и паролю явно выберите TRINO_AUTH_METHOD=basic.
По умолчанию стоит none: один TRINO_USER не включает отправку пароля.
TRINO_AUTH_SECRET_ENV содержит имя переменной с паролем, а не сам пароль.
Basic требует HTTPS с проверкой сертификата, в том числе при локальном запуске.
1. Подготовьте окружение и доступ¶
python3 -m venv /ABSOLUTE/PATH/trino-env
/ABSOLUTE/PATH/trino-env/bin/python -m pip install 'agent-paranoid-android[mcp,trino]'
/ABSOLUTE/PATH/trino-env/bin/test-data-agent --version
/ABSOLUTE/PATH/trino-env/bin/test-data-agent doctor --require-extra trino
Замените /ABSOLUTE/PATH своим абсолютным путём. Doctor проверяет локальную
установку, а не вход на сервер. У администратора Trino уточните HTTPS host/port,
логин, разрешённые catalog/schema/table/column и права чтения метаданных и
агрегатов. Из среды MCP должны быть доступны сервер, при необходимости VPN,
и доверенная цепочка сертификата. Корпоративный CA должен быть доверенным в
используемом Python/окружении; отключать проверку TLS не нужно.
2. Передайте пароль процессу¶
Если MCP-клиент умеет передавать секреты в окружение дочернего процесса через
защищённое хранилище, создайте там MY_TRINO_PASSWORD. Не помещайте пароль в
JSON, репозиторий, аргументы команды или переписку. Переменная из терминала
не обязательно видна графическому приложению; файл .env автоматически не
загружается. После изменения настроек перезапустите MCP-сервер.
Готовый вариант для macOS: в приложении «Связка ключей» создайте запись
пароля с именем agent-paranoid-android-trino, учётной записью, совпадающей с
TRINO_USER, и вашим паролем. Сохраните следующий скрипт как
/ABSOLUTE/PATH/start-trino-mcp.sh, заменив путь к установленному серверу:
#!/bin/bash
# Пароль читается локально; stdout используется только протоколом MCP.
if ! MY_TRINO_PASSWORD=$(/usr/bin/security find-generic-password \
-s agent-paranoid-android-trino -a "$TRINO_USER" -w 2>/dev/null); then
printf '%s\n' 'Trino password is unavailable in Keychain' >&2
exit 1
fi
export MY_TRINO_PASSWORD
exec /ABSOLUTE/PATH/trino-env/bin/test-data-agent-mcp-trino
Выполните chmod 700 /ABSOLUTE/PATH/start-trino-mcp.sh. Разрешите локальному
запуску чтение нужной записи, если macOS запросит доступ. Не включайте set -x
и не добавляйте печать пароля. Этот вариант получает секрет при запуске и не
зависит от наследования окружения графическим приложением. Для другой ОС
используйте защищённое хранилище клиента или локальный механизм секретов.
3. Добавьте сервер в MCP-клиент¶
Это распространённый формат mcpServers; точное место настройки зависит от
клиента. Все адреса, логины и имена данных ниже вымышлены — замените их локально.
Пример использует скрипт со Связкой ключей из предыдущего шага:
{
"mcpServers": {
"trino": {
"command": "/ABSOLUTE/PATH/start-trino-mcp.sh",
"env": {
"TRINO_HOST": "trino.example.internal",
"TRINO_PORT": "443",
"TRINO_HTTP_SCHEME": "https",
"TRINO_USER": "your_login",
"TRINO_AUTH_METHOD": "basic",
"TRINO_AUTH_SECRET_ENV": "MY_TRINO_PASSWORD",
"TRINO_ALLOWED_CATALOGS": "warehouse",
"TRINO_ALLOWED_SCHEMAS": "analytics",
"TRINO_ALLOWED_TABLE_COLUMNS": "warehouse.analytics.orders.*",
"TRINO_DEPLOYMENT_PROFILE": "shared-hardened",
"TRINO_MAX_INVOCATION_ESTIMATED_SCAN_BYTES": "1073741824"
}
}
}
}
При передаче MY_TRINO_PASSWORD защищённым механизмом клиента вместо Связки
ключей задайте command напрямую:
/ABSOLUTE/PATH/trino-env/bin/test-data-agent-mcp-trino.
Синтаксис подстановки секретов зависит от клиента: ${MY_TRINO_PASSWORD}
в JSON не является универсальной подстановкой.
TRINO_HOST — только имя сервера, без схемы URL и пути; порт должен совпадать
с HTTPS endpoint. Catalog/schema — обязательные allowlists через запятую.
Column scope необязателен для обычных таблиц, но обязателен для profile-query.
Вместо warehouse.analytics.orders.* можно перечислить точные столбцы через
запятую. Wildcard разрешает только ограниченное агрегатное профилирование,
не выдаёт права на исходные строки и не заменяет grants в Trino.
Указанный cumulative scan budget — 1 ГиБ на вызов. По умолчанию действуют
также request timeout 30 секунд, execution time 30 секунд, run time 45 секунд
и scan budget 1 ГиБ на запрос. TRINO_CATALOG и TRINO_SCHEMA — необязательные
значения по умолчанию внутри allowlists. Полный список — в
справочнике конфигурации.
4. Проверьте запуск и разберите ошибку¶
Перезапустите сервер в MCP-клиенте и убедитесь, что появились Trino-инструменты.
Сначала вызовите разрешённый инструмент метаданных, например list_catalogs,
затем describe_table для согласованной таблицы. Успешный запуск процесса и
Doctor не доказывают успешную аутентификацию. Эти инструкции проверены локально
по конфигурационному контракту; вход на ваш сервер не проверен.
При 401 локально проверьте basic, доступность переменной, указанной в
TRINO_AUTH_SECRET_ENV, правильность логина и перезапуск процесса. При 403
проверьте серверные права и политику доступа; сам статус не устанавливает
точную причину. Ошибки TLS требуют проверки endpoint и доверия сертификату.
Для обращения за помощью достаточно версии пакета, способа запуска,
TRINO_AUTH_METHOD, TRINO_HTTP_SCHEME, признаков «логин задан»,
«secret reference задан», «переменная с паролем доступна процессу» и результата
входа другим клиентом. Не передавайте значения логина/пароля, полный .env,
URL подключения, исходные строки или необработанные ответы драйвера.
Ошибки аутентификации¶
При сбое запишите локально версию пакета и выбранный TRINO_AUTH_METHOD.
Для разбора достаточно этих сведений: не передавайте пароли, токены, адреса
подключения и необработанные ответы драйвера. Один код HTTP 401 не позволяет
установить причину сбоя настройки или совместимости.
Профилирование SQL-запроса преобразует нетипизированные ошибки HTTP 401/403
и TLS в фиксированную ошибку SQL query source profiling failed, не сохраняя
исходное исключение в cause или context. CLI сохраняет категорию
external_service и прежний выходной файл. MCP возвращает фиксированную
ошибку Trino, а аудит не содержит значений источника или секретов.
Эти проверки не подтверждают успешный вход на конкретный сервер.
Трансформация локальных данных¶
English · Русский
Для чего это нужно¶
Используйте эту opt-in операцию, когда нужна обработка один к одному по явной policy: drop, synthesize, substitute, replace_text и разрешённое preserve. Выход имеет смешанное происхождение (mixed-origin); его нельзя выдавать за полностью синтетический или анонимный набор.
Что получится в результате¶
В примере — value-free review, точный snapshot digest и новая локальная таблица с двумя явно заданными заменами. Сохранение source values и issuance receipt здесь не выполняются.
Предварительные требования¶
Базовая установка 1.6.0, активное окружение, терминал в корне checkout на macOS/Linux. Папки out/ru-transform и out/ru-transform-output не существуют. Только вымышленные данные ниже. Политика и schema fingerprint рассчитаны именно для этих bytes и entity items; для другого источника они не подходят. Bash heredoc на Windows заменяется локальным Python-файлом; Windows-выполнение не проверено.
Пошаговое выполнение¶
Шаг 1. Подготовьте вымышленный источник и policy¶
Что сделать: запишите три небольших локальных файла без реальных данных.
Где выполнить: терминал, корень checkout.
Команда или пример:
python - <<'PYCODE'
from pathlib import Path
p = Path('out/ru-transform')
p.mkdir(parents=True, exist_ok=False)
(p / 'items.csv').write_bytes(b'status\nready\nwaiting\n')
(p / 'map.csv').write_bytes(b'old,new\nready,done\nwaiting,pending\n')
(p / 'policy.yaml').write_text("""schema_version: '0.1'
schema_fingerprint: bcc0d673c3991184ddadf0acdffeb759fd65f53b4ec65b6367bc3cfd5fdb72cc
seed: 7
fields:
- entity: items
field: status
sensitivity: non_sensitive
behavior:
action: substitute
mapping:
kind: csv
path: map.csv
source_columns: [old]
replacement_columns: [new]
""", encoding='utf-8')
PYCODE
Что должно произойти: создана ограниченная policy с явными replacement values в локальном mapping. Ни одна ветка не разрешает preserve fallback.
Как проверить: файлы в одной папке; map.csv задаётся относительно policy, не текущего shell.
Если не получилось: выберите новую папку; не подставляйте неизвестный источник под этот fingerprint.
Шаг 2. Получите review без значений¶
Что сделать: прочитайте fixed snapshot; сохраните JSON только в новый файл.
Где выполнить: корень checkout.
Команда или пример:
test-data-agent transform-review out/ru-transform/items.csv out/ru-transform/policy.yaml --trace --json > out/ru-transform/review.json
Что должно произойти: result.status=review_only; review содержит решения полей, digest и ordinal trace без literals.
Как проверить: код 0; snapshot_sha256 имеет 64 hex-символа; receipt не создан.
Если не получилось: не используйте перенаправленный JSON после ненулевого кода. Проверьте policy, schema, пути и бюджеты; не выдавайте новый hash за старое approval.
Что сделать: используйте digest только что проверенного фиксированного плана. Этот пример не содержит preserve, поэтому preservation receipt не нужен.
Где выполнить: корень checkout; policy, mapping и source после review не менялись.
Команда или пример:
python - <<'PYCODE'
import json
import subprocess
from pathlib import Path
p = Path('out/ru-transform')
r = json.loads((p / 'review.json').read_text())['result']
assert r['status'] == 'review_only'
subprocess.run([
'test-data-agent', 'transform-execute', str(p / 'items.csv'),
str(p / 'policy.yaml'), 'out/ru-transform-output',
'--snapshot-sha256', r['snapshot_sha256'],
'--max-total-input-bytes', '8192', '--max-output-bytes', '8192', '--json',
], check=True)
PYCODE
Что должно произойти: создан mixed-origin bundle; summary содержит transformation_completed и provenance, не строки.
Как проверить: код 0; digest соответствует review; replacement counters отражают две ячейки, original — ноль. Не требуйте synthetic=true от transformation manifest.
Если не получилось: при изменении любого bound input нужен новый review; не переиспользуйте receipt или digest. Cleanup-incomplete требует локальной проверки staging/output, а не overwrite.
Проверка результата¶
Прочитайте value-free report/provenance созданного bundle. Подтвердите ноль original и две replacement ячейки. Не отправляйте transformed rows в AI: explicit mapping может законно совпадать с другими source values, включая sensitive permutations, а mixed-origin output остаётся потенциально чувствительным.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
| Stale snapshot / invalid transformation request | После review изменились source/policy/mapping bytes | Получите новый review; сохранение требует нового local approval |
| Требуется receipt | Выбрано preserve либо preserve fallback | Остановитесь для человека в local controlling-TTY |
| Cleanup incomplete | Не подтверждено полное удаление staging/output | Проверьте состояние локально; не перезаписывайте результат |
Когда нужен человек¶
transform-approve SOURCE POLICY RECEIPT --snapshot-sha256 SHA выдаёт receipt только после свежего ввода APPROVE в управляющем локальном терминале. Агент и MCP не могут вводить это за человека, подменять подтверждение флагом/pipe или имитировать терминал. Receipt привязан к exact source, policy, classification и mapping bytes. Sensitive/unknown/disputed поля не разрешены для preserve; DECIMAL preservation по умолчанию заблокирован. Локальный wizard transform-review --decide и SAVE сохраняют policy, но не создают receipt.
transform-batch объединяет минимум два входа и независимо проверенный validation spec. create сохраняет references/policies, review выдаёт digest, approve — local-only receipt, validate проверяет временный выход, execute может сохранить новый direct-child bundle. Обязательны явные input/review/output caps согласно справке. common_transformation MCP использует ту же границу; configured_query_session/transform-batch query-execute отдельно захватывают разрешённые SQL results один раз и потребляют frozen batch без reconnect. Нет MCP receipt issuer.
Следующий шаг¶
Полная справка CLI, публичный контракт и границы безопасности. Локальный review и explicit replacement пример проверены; интерактивный preserve и live SQL session в этом аудите не выполнялись.
Интеграции
Подключить MCP-клиент¶
English · Русский
Для подключения Trino по логину и паролю используйте готовый пример настройки MCP.
Для чего это нужно¶
MCP позволяет клиенту вызывать генератор и получать сводки и пути к артефактам. Разделяйте процесс генерации с файловым workspace и процесс чтения Trino.
Что получится в результате¶
Клиент видит инструменты generator; профиль и spec остаются внутри заданной папки.
Предварительные требования¶
Установлен extra mcp; для Trino также trino. Нужен MCP-клиент с поддержкой stdio (обмена сообщениями через стандартные потоки). Конкретный интерфейс клиента не проверен выполнением. Проверка SDK и регистрации выполняется локальными тестами.
Пошаговое выполнение¶
Шаг 1. Создайте отдельную рабочую папку¶
Что сделать: Создайте out/ru-mcp из корня проекта и узнайте её абсолютный путь.
Где выполнить: Терминал, корень checkout.
Команда или пример:
python -c "from pathlib import Path; p=Path('out/ru-mcp'); p.mkdir(parents=True, exist_ok=False); print(p.resolve())"
Что должно произойти: Напечатан абсолютный путь.
Как проверить: Это обычная новая папка; не домашняя папка целиком и не корень диска.
Если не получилось: Если папка есть, выберите новое имя. Не используйте широкую область доступа.
Шаг 2. Добавьте сервер в клиент¶
Что сделать: В конфигурации своего клиента замените оба placeholder на полученные реальные абсолютные пути. Путь command — исполняемый файл из вашего окружения.
Где выполнить: Локальный конфигурационный файл MCP-клиента.
Команда или пример:
{
"mcpServers": {
"test-data-agent-generator": {
"command": "/ABSOLUTE/PATH/.venv-ru/bin/test-data-agent-mcp-generator",
"env": {"TEST_DATA_AGENT_WORKSPACE_ROOT": "/ABSOLUTE/PATH/out/ru-mcp"}
}
}
}
Что должно произойти: При запуске клиента поднимается generator stdio server.
Как проверить: В списке инструментов клиента есть plan_dataset и inspect_dataset_plan.
Если не получилось: На Windows command указывает на .venv-ru\Scripts\test-data-agent-mcp-generator.exe. Проверьте синтаксис клиента, extra и права; не вставляйте secrets в JSON.
Шаг 3. Проверьте локальный SDK¶
Что сделать: Проверьте доступность generator tool registration.
Где выполнить: Терминал с активным окружением.
Команда или пример:
test-data-agent doctor --require-extra mcp
Что должно произойти: Проверка локального MCP проходит без запуска внешнего сервиса.
Как проверить: Код 0; это не проверка конфигурации конкретного клиента.
Если не получилось: Если missing_dependency, установите .[mcp] тем же интерпретатором.
Проверка результата¶
Положите только разрешённый синтетический CSV в workspace. В клиенте сначала вызовите plan_dataset, затем inspect_dataset_plan; генерация должна ждать review точного spec. Инструменты, аргументы и JSON-примеры: MCP Tools.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
Tool arguments failed validation |
Аргументы не соответствуют схеме | Запросите tools/list; исправьте типы, не повторяйте чувствительный payload в чате. |
Invalid request parameters |
Некорректный MCP/JSON-RPC запрос | Используйте совместимый SDK и корректную схему. |
unsafe filesystem path |
Путь вне workspace или symlink | Перенесите разрешённый файл в обычную папку workspace. |
Безопасная последовательность инструментов¶
plan_dataset: источник внутри workspace, новый agent workspace, count, seed, format.inspect_dataset_plan: прочитать checklist иreview.current_spec_sha256.- Человек проверяет
dataset_spec.yamlи именно этот fingerprint. approve_dataset_plan: передать одобренныйreviewed_spec_sha256.- Проверить manifest и validation; сообщить только сводку и пути.
Для Trino сначала profile_table_safe, затем plan_trino_dataset и тот же review. Другие этапы доступны отдельно: profile_csv, infer_dataset_spec, generate_dataset, validate_dataset. Наличие низкоуровневого инструмента не отменяет согласованную политику review.
Trino default aggregate-only инструменты возвращают метаданные без исходных литералов. Отдельный explicit opt-in run_safe_select включается через TRINO_ENABLE_SAFE_SELECT; он маскирует строки, но может сохранять нечувствительные нестроковые значения источника. Такой результат не является анонимным или source-free; его нельзя передавать LLM или использовать как сгенерированные данные. Не включайте этот инструмент для описанного workflow.
Generator ограничивает пути workspace, но это не sandbox процесса. Используйте отдельного системного пользователя/контейнер для недоверенных клиентов. Значения по умолчанию: frame 1 MiB, response 4 MiB, 32 active requests; Trino дополнительно ограничивает работу и параллельность. См. границы MCP и аудит.
Следующий шаг¶
Отдельные инструменты трансформации 1.6.0¶
Generator MCP также регистрирует execute_transformation, common_transformation и configured_query_session. Они возвращают ограниченные метаданные и пути, не строки. Наличие инструмента не разрешает обработку набора или сохранение source values. MCP и агент не выдают preservation receipts: человек делает это отдельно в local controlling-TTY. Capture использует согласованные read-only scopes; исполнение должно потреблять тот же frozen batch без повторного подключения. См. трансформацию и MCP contract.
TEST_DATA_AGENT_MCP_MAX_INVOCATION_SECONDS по умолчанию 120 секунд задаётся server-side; tool arguments его не расширяют. Независимые лимиты генерации, ввода/вывода и правил остаются в силе.
AI-интеграция¶
English · Русский
Для чего это нужно¶
Advisor помогает предложить изменения DatasetSpec по безопасным метаданным. Его предложение проходит детерминированную проверку, а человек повторно проверяет итоговый контракт.
Что получится в результате¶
Локальный review-first workspace и ограниченный advisor exchange JSON. Внешняя отправка не выполняется этими шагами.
Предварительные требования¶
Установлен Python 3.11+ и пакет проекта. Терминал открыт в корне репозитория agent-paranoid-android; виртуальное окружение активно. Входы — только вымышленные файлы из репозитория. Папка назначения новая; есть права чтения входов и записи результата. Для команд ниже используйте macOS/Linux; в PowerShell вводите каждую команду одной строкой без \. Внешние provider-вызовы не проверялись. Для локального plan/request extra openai не требуется.
Пошаговое выполнение¶
Шаг 1. Подготовьте план¶
Что сделать: Создайте workspace из вымышленного CSV и остановитесь до генерации.
Где выполнить: Корень checkout.
Команда или пример:
test-data-agent agent-plan examples/csv_quickstart/customers.csv --workspace out/ru-agent --count 25 --seed 12345 --format csv
Что должно произойти: Созданы profile/spec и состояние ожидания review.
Как проверить: agent-status сообщает awaiting_approval.
Если не получилось: При занятом workspace выберите новую папку; не удаляйте исходные артефакты.
Шаг 2. Посмотрите review¶
Что сделать: Получите безопасный checklist и отпечаток текущего spec.
Где выполнить: Корень checkout.
Команда или пример:
test-data-agent agent-review out/ru-agent
test-data-agent agent-status out/ru-agent --json
Что должно произойти: Показаны поля, предположения, privacy и fingerprint.
Как проверить: Статус ожидает одобрения; generation ещё не выполнена.
Если не получилось: Если источник или spec изменился, заново постройте план или повторите review.
Шаг 3. Сохраните exchange локально¶
Что сделать: Создайте файл только если out/ru-advisor-exchange.json ещё не существует: перенаправление shell само по себе перезаписывает файл.
Где выполнить: Корень checkout.
Команда или пример:
test-data-agent agent-advisor-request out/ru-agent --exchange > out/ru-advisor-exchange.json
Что должно произойти: Записаны trusted instructions, untrusted metadata и schema AdvisorProposal.
Как проверить: JSON читается, содержит fingerprint-bound request; исходных строк нет.
Если не получилось: При ненулевом коде не передавайте файл провайдеру: shell мог оставить пустой/ошибочный файл. Проверьте статус workspace.
Проверка результата¶
Перед любой внешней отправкой человек проверяет метаданные, имена таблиц/полей, разрешённого провайдера и политику организации. Даже агрегаты и имена могут раскрывать контекст. Сохранение exchange — локальная операция, не разрешение на передачу.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
| Workspace не awaiting_approval | Уже завершён или находится в другой фазе | Выполните agent-status; действуйте по его next action. |
| Proposal не совпадает с fingerprint | Изменился request/spec | Создайте новый exchange; не подменяйте отпечаток. |
Необязательное обращение к провайдеру¶
После явного разрешения передачи и установки .[openai] можно выполнить test-data-agent agent-advise out/ru-agent --provider openai. Runtime OPENAI_API_KEY должен внедряться секретным механизмом, не попадать в команды или файл проекта. OpenAI и GigaChat — экспериментальные provider adapters. Для GigaChat: extra gigachat, --provider gigachat; используйте ровно один из GIGACHAT_CREDENTIALS и GIGACHAT_ACCESS_TOKEN. TLS обязателен. Эти сетевые команды не проверены выполнением в аудите; квота, модель и доступность требуют отдельной проверки.
Для внешнего ручного обмена ответ сохраняется как bounded JSON и принимается через test-data-agent agent-advisor-apply out/ru-agent advisor_proposal.json. Схема ответа находится внутри exchange; не придумывайте proposal и не редактируйте spec в обход валидатора.
После любого применения предложения снова выполните agent-review, прочитайте изменённый spec и получите согласие на точный fingerprint. Только затем agent-approve out/ru-agent --reviewed-spec-sha256 <ОДОБРЕННЫЙ_SHA256> (placeholder заменяется реальным значением; не вставляйте угловые скобки в shell). Нельзя автоматически одобрять всё, что предложил provider.
AI не создаёт строки напрямую, не придумывает таблицы и связи вне локальных кандидатов и не получает право отключать safety. --local-category не разрешает передавать исходные enum провайдеру: они заменяются field-scoped synthetic labels. Подробный контракт advisor и интеграция.
Следующий шаг¶
Работа в контейнерах¶
English · Русский
Контейнеры — отдельный способ запуска CLI/MCP worker. Для локального Python обычный путь — PyPI. Образы 1.6.0 опубликованы с проверяемыми digest/signature.
| Образ GHCR, префикс ghcr.io/wa-pis/ | Entrypoint | Возможности |
|---|---|---|
| agent-paranoid-android-cli | test-data-agent | Core CSV/JSON |
| agent-paranoid-android-generator-mcp | test-data-agent-mcp-generator | Core + MCP |
| agent-paranoid-android-trino-mcp | test-data-agent-mcp-trino | Core + MCP + Trino/SQLGlot |
Выберите tag 1.6.0, затем разрешите и проверьте immutable digest. Latest, 1 и 1.6 — mutable aliases. Публикуются linux/amd64 и linux/arm64; PyArrow не входит, для Parquet используйте Python extra.
Локальная сборка¶
Из корня checkout можно собрать только нужный target; Docker-выполнение здесь не проверялось:
docker build --target cli -t agent-paranoid-android:cli .
docker build --target generator-mcp -t agent-paranoid-android:generator-mcp .
docker build --target trino-mcp -t agent-paranoid-android:trino-mcp .
Compose использует non-root UID/GID (по умолчанию 65532), read-only root, dropped capabilities, no-new-privileges, конечные CPU/memory/process/tmp limits и не публикует ports. Writable workspace/audit mounts и отдельные owner-only secret files готовятся администратором. CONTAINER_UID/GID не могут быть нулевыми. Не коммитьте workspace, audit и secrets.
Generator получает /workspace и /audit без network. Он подходит для synthetic/local-file работы и не может молча получить DB capture access. Trino worker имеет outbound network, узкие HTTPS allowlists и read-only роль; generator workspace ему не монтируется.
MCP client запускает docker compose run --rm -T generator-mcp через stdio. Это не HTTP endpoint. Deadline TEST_DATA_AGENT_MCP_MAX_INVOCATION_SECONDS по умолчанию 120 секунд; остальные budgets остаются независимыми.
Audit и проверка образа¶
У workers разные ключи и audit mounts. Key file передаётся через /run/secrets, не image metadata или открытый client config. Перед rotation остановите соответствующего writer.
Перед запуском проверьте digest через Cosign, GitHub attestation и SBOM по точным командам оригинального руководства — English. Они требуют опубликованного digest, не placeholder. Health проверяет только локальные dependencies, non-root, workspace и configuration; он не соединяется с Trino и не читает набор.
Справочник
Справочник¶
English · Русский
Начните с инструкции по задаче. Здесь собраны точные команды, схемы и контракты интеграций.
Команды и автоматизация¶
Контракт данных¶
- Матрица источников и форматов, проверенные DECIMAL/Parquet примеры.
- Режимы и overwrite.
- DatasetSpec, совместимость схемы.
- Профилирование CSV, связи.
- Миграция, aliases.
- Стабильность, runtime support, dependency compatibility — English.
Интеграции¶
- MCP tools, права, audit.
- AI, операционные workflows агента.
- Advisor API — English, GigaChat — English.
- Собственный advisor — English, semantic provider — English.
Дополнительно¶
Модель угроз, пилот, workflow, история, проверка перевода и примеров.
Основные пользовательские страницы и справочники переведены. Непереведённые специализированные API tutorials и исторические записи помечены English; они открываются в оригинале. Перевод не меняет статус или контракт этих страниц.
Возможности и выбор способа работы¶
English · Русский
В таблице указаны входы, результаты и ситуации, когда функцию применять не стоит. Практическая проверка находится в соответствующей инструкции.
| Возможность | Когда использовать; вход | Результат | Когда не подходит; ограничение | Проверка |
|---|---|---|---|---|
| Офлайн-демо | Нужно проверить установку; встроенная фикстура | 12 синтетических покупателей и отчёты | Не доказывает качество связей и бизнес-правил | Первый запуск |
| CSV | Одна таблица; CSV с заголовком | Данные, профиль, спецификация, manifest | Не для копирования или обезличивания строк один к одному | CSV |
| Папка CSV | Связанные таблицы; один файл на сущность | Профиль, предположения о связях, набор таблиц | Найденные зависимости требуют проверки; выборка ограничена | Основной процесс |
| DatasetSpec | Нужен явный контракт; YAML/JSON | Управляемые строки и отчёты | Не выполняет произвольный Python, SQL или текстовые правила | Настройка |
| Parquet-профиль | Нужны безопасные метаданные Parquet; profile-parquet | Профиль, затем reviewed spec | Неизвестные null-статистики и DECIMAL bounds требуют явного контракта | Parquet |
| Точный DECIMAL | Финансовые тесты; DatasetSpec 1.1 с decimal_range | Точные десятичные значения | FLOAT не заменяет DECIMAL; bounds задаются человеком | DECIMAL |
| Seed | Нужен повтор; спецификация и целое число ≥0 | Повторяемые данные в том же окружении | Не обещает побайтовое совпадение между версиями и платформами | CSV |
| Валидация | Нужно проверить сгенерированную папку по spec | Секции schema, relationships, constraints, privacy | Не доказывает полезность и анонимность | Валидация |
| CSV/JSON/SQL/Parquet | Нужно передать результат тестовой системе | Файлы сущностей | Parquet требует extra; общий SQL не содержит DDL | Форматы |
| PostgreSQL/Trino | Разрешено читать метаданные и агрегаты | Профиль без исходных строк | Не для произвольных запросов, записи или экспорта строк | Базы |
| Бизнес-правила | Нужны формулы, условия, связи, сценарии | Данные и business_validation_report | Не все правила могут исправляться генератором | Правила |
| MCP | Нужен вызов инструментов AI-клиентом | Метаданные и пути к локальным артефактам | Ограничение workspace не заменяет изоляцию процесса | MCP |
| AI advisor | Требуется предложение к spec по метаданным | Проверяемое предложение с повторным review | Не для отправки строк и автоматического одобрения | AI |
Базовые CSV, JSON, SQL, CLI, DatasetSpec и валидация доступны без внешних сервисов. Parquet, базы, MCP и AI подключаются отдельными extras. GigaChat обозначен в коде как экспериментальный. В 1.6.0 зарегистрирована отдельная selective transformation: локальные transform-review/approve/execute, transform-batch и MCP consumers. Это mixed-origin обработка один к одному, а не синтетическая генерация; разрешение на набор и локальный receipt не выдаются агентом. См. инструкцию.
Подробнее: ограничения.
Профили и спецификации¶
English · Русский
Профиль описывает наблюдаемую структуру и ограниченные агрегаты источника; DatasetSpec задаёт исполняемый проверенный контракт. Generation использует spec, а не исходные строки. Профиль может содержать nullable/distinct/length/distribution evidence и кандидаты связей, но не source rows, PII или secrets.
Новые DatasetSpec используют 1.1, legacy 1.0 поддерживается без decimal. Import payload без версии трактуется как 1.0, новый Python DatasetSpec по умолчанию — 1.1. Укажите версию явно.
SQL query-source policy 1.1 допускает ограниченный single-table SELECT, scalar expressions и aliased SUM/COUNT/MIN/MAX/AVG с ограниченным GROUP BY. JOIN/CTE/subqueries/windows/HAVING/неизвестные функции отклоняются. Профиль хранит fingerprint, а не SQL text или result rows. has_unmodeled_expressions=true (в том числе aggregate) блокирует automatic infer-spec: напишите независимо проверенный spec. Direct column aliases могут выводиться автоматически; старые query profiles без marker нужно получить заново.
Практика: раздельный процесс, поля DatasetSpec, конфигурация.
Проект создаёт новые синтетические данные для тестирования программ. Он анализирует структуру CSV или разрешённые агрегаты базы, составляет DatasetSpec, генерирует значения и проверяет результат. Исходные строки не копируются в результат.
Например, команде разработки нужны 25 заказов с корректными ссылками на покупателей, но реальные покупатели не должны попадать в тестовую среду. Можно использовать вымышленный CSV, проверить выведенную спецификацию и получить новый набор с явным seed.
Проект подходит для воспроизводимых тестовых фикстур, проверки схем, связей и формализованных бизнес-правил. Он не гарантирует полную статистическую точность исходного набора, анонимность, юридическое соответствие или сохранение всех правил предметной области.
flowchart LR
A[CSV или разрешённые агрегаты БД] --> B[Безопасный профиль]
B --> C[DatasetSpec]
C --> D[Проверка человеком]
D --> E[Генерация с seed]
E --> F[Валидация]
F --> G[Файлы и отчёты]
AI-сервис необязателен. Он может предложить изменения спецификации; генерацию и проверки выполняет детерминированный код.
Далее: возможности, затем установка.
Термины¶
| Термин | Значение |
|---|---|
| Синтетические данные | Новые значения, созданные генератором по спецификации |
| CSV | Текстовая таблица с заголовком и разделителями |
| Сущность / entity | Одна таблица; обычно имя CSV без расширения |
| Поле / field | Один столбец таблицы |
| Профиль / DatasetProfile | Метаданные: типы, количества, диапазоны, распределения и кандидаты связей |
| DatasetSpec | Проверяемый контракт генерации и валидации, YAML или JSON |
| DECIMAL | Точное десятичное число с precision (числом цифр) и scale (числом дробных разрядов) |
| Mixed-origin | Артефакт трансформации с происхождением ячеек replacement/synthetic/original; не является целиком synthetic |
| Receipt | Локальное подтверждение сохранения значений, привязанное к точному snapshot; выдаётся человеком в управляющем терминале |
| Seed | Начальное число локального генератора случайных значений |
| Детерминированность | Повтор результата при одинаковых входах, seed и окружении |
| Primary key | Поле уникального идентификатора строки |
| Foreign key | Ссылка дочерней строки на ключ родительской таблицы |
| Distribution | Правило распределения значений: например категории или числовой диапазон |
| Constraint | Структурированное ограничение, например порядок дат или формула |
| Manifest | generation_manifest.json: сведения о генерации, seed, проверках и окружении |
| Валидация | Проверка результата по заданным правилам |
| PII | Personally Identifiable Information: персональные и позволяющие идентификацию данные |
| Allowlist | Явный список разрешённых объектов или полей |
| CLI | Command-line interface: команды в терминале |
| MCP | Model Context Protocol: протокол вызова инструментов клиентом |
| Advisor | Необязательный AI-провайдер, предлагающий изменения spec |
| Workspace | Выделенная рабочая папка артефактов |
| SHA-256 / fingerprint | Отпечаток точного содержимого; изменение файла меняет отпечаток |
| Extra | Необязательная группа зависимостей Python-пакета |
| Exit code | Числовой код завершения команды; проверяется автоматизацией |
confidence — оценка уверенности, status — статус предположения. Они не превращают найденную связь в доказанный закон предметной области. unique_ratio_kind=lower_bound означает нижнюю границу уникальности, а не точную долю.
Далее: требования.
Границы дат и времени¶
В проверенной спецификации date_range и datetime_range задают границы
генерации. Пропущенные границы заменяются на 2020-01-01 и 2025-01-01.
Для более раннего или позднего периода укажите обе границы в правильном
порядке: частичная граница, противоречащая значению по умолчанию, теперь
вызывает отказ с подсказкой. Прежние выходные файлы при этом сохраняются.
Смещение времени по-прежнему выбирается с точностью до целой секунды и сохраняет микросекунды нижней границы. Для длинных интервалов используется целочисленная длительность, чтобы не выйти за максимум при округлении. Минимум и максимум не доказывают месячную или иную календарную гранулярность; соответствие периодам источника остаётся неизмеренным.
Безопасность данных¶
English · Русский
Почему синтетические данные всё равно нужно проверять¶
Отсутствие копирования строк — важная гарантия, но не доказательство анонимности. Имена таблиц, поля, агрегаты, редкие сочетания, бизнес-категории и вручную записанные правила могут раскрывать контекст. Эвристика не всегда понимает специфичный для организации идентификатор. Профиль и spec тоже нуждаются в review перед передачей.
Генератор не сертифицирует differential privacy, k-anonymity, защиту от всех атак повторной идентификации или юридическое соответствие. Безопасность назначения оценивает владелец данных.
Обязательные границы¶
- Не копировать, не перемешивать и не экспортировать исходные строки как synthetic output.
- Не включать PII, credentials, токены, secret и production literals в примеры, правила, логи, исключения и provider payload.
- Читать внешнюю базу только в разрешённом scope, read-only ролью, с конечными бюджетами и TLS.
- Разделять создание локальных файлов и выполнение SQL-записи в целевой БД.
- Использовать отдельные входные и выходные пути; не обходить отказ при symlink или выходе за workspace.
- Проверять AI-предложение детерминированно, затем выполнять человеческий review точного spec.
--local-category разрешает только отдельные проверенные ограниченные enum/константы в локальных разрешённых назначениях, не исходные строки, идентификаторы, свободный текст или передачу провайдеру. Установленный allowlist — вход авторизации, а не доказательство нечувствительности содержимого.
Процедура безопасного принятия¶
- До чтения: подтвердите разрешённые файлы/таблицы/поля и назначение. Для неизвестного источника остановитесь до уточнения, не берите sample rows в чат.
- После профиля: локально проверьте метаданные и чувствительность; не публикуйте артефакт автоматически.
- После spec: проверьте identifiers, категории, даты, связи, ограничения и объём; сохраните точный fingerprint при review-first workflow.
- После генерации: выполните валидацию, проверьте manifest и бизнес-отчёт, оцените полезность и риск раскрытия.
- Перед передачей: подтвердите получателя, среду и разрешение; отправляйте только разрешённый результат. Нельзя автоматически пересылать исходные данные внешнему AI даже для диагностики.
Для каждой проверки критерий успеха — явный подтверждённый scope или отчёт; при неопределённости прекратите зависимую операцию и запросите недостающий факт. Подробные исполнимые шаги и ошибки: agent workflows.
Trino default aggregate-only инструменты отделены от explicit opt-in run_safe_select. Последний возвращает ограниченный row-shaped результат и не гарантирует отсутствия всех исходных значений. Он не нужен для генерации и не может быть её источником строк.
Дополнительно: Safety Model, Threat Model, ограничения.
Трансформация не является синтетической генерацией¶
В 1.6.0 отдельная opt-in трансформация создаёт labelled mixed-origin артефакты один к одному. Перед preserve или preserve fallback нужны явное field-scoped non-sensitive решение, отсутствие conflicting sensitivity, комментарий оператора и свежий локальный controlling-TTY receipt для exact snapshot. Sensitive/unknown/disputed поля не разрешаются; DECIMAL preservation по умолчанию заблокирован. Receipt не выдаёт агент или MCP.
Явные substitute/replace_text mappings имеют отдельный контракт: replacement может совпасть с другим исходным значением, включая sensitive permutation. Это не разрешает implicit copying, source-row reuse в генерации или раскрытие literals в логах/provider/MCP. Такой выход защищают как потенциально чувствительный; synthetic=true/source_rows_copied=false не следует приписывать ему по аналогии с генератором. См. отдельный workflow.
Ограничения и неподтверждённые свойства¶
| Область | Подтверждённая граница | Что нельзя обещать |
|---|---|---|
| Повторяемость | Явный seed и одинаковое окружение | Одинаковые байты на любых версиях/ОС |
| Профиль | Ограниченные метаданные и наблюдения | Полную статистическую модель исходных данных |
| Правила | Только формализованные поддерживаемые ограничения | Сохранение неизвестных бизнес-законов |
| Связи | Кандидаты с confidence/status, проверка сгенерированных ссылок | Что любая найденная связь имеет верный бизнес-смысл |
| CSV-папка | Ограниченная выборка и distinct tracker | Точную уникальность после overflow; lower_bound — лишь нижняя граница |
| Identifier pool | Синтетическое число ключей и детерминированное циклирование | Сохранение исходных ID, частот или row mappings |
| Время | При отсутствии границ fallback 2020-01-01 / 2025-01-01 | Что fallback — измеренный период источника |
| Приватность | Content guards и запрет копирования строк | Сертификат анонимности, юридическое соответствие |
| SQL source | Ограниченный single-table SELECT, no-row schema и агрегаты | JOIN, CTE, arbitrary SQL или source-row export |
| SQL output | Генерация файла | Автоматическую загрузку в БД или проверенное исполнение SQL |
| Workspace | Проверка путей generator MCP | OS sandbox, сетевую изоляцию, защиту от владельца процесса |
| Файлы | Staging и recovery некоторых interrupted approvals | Полную crash/power-loss durability нескольких файлов как одной транзакции |
| AI | Ограниченные proposals, детерминированная валидация, review | Достоверность всех рекомендаций или auto-approval |
| Selective transformation | Зарегистрированные local/MCP consumers с exact snapshot и receipt gates | Что регистрация разрешает набор, выдачу approval агентом или анонимность mixed-origin output |
OpenAI и GigaChat adapters имеют статус experimental. load_test — режим генерации, а не распределённая нагрузочная платформа; edge не доказывает покрытие всех границ вашей системы. Для negative/mixed проверяйте ожидаемые нарушения.
Не подтверждено этим аудитом: новая установка из индекса, Windows/Linux, живые PostgreSQL/Trino, вызовы OpenAI/GigaChat, конкретный MCP-клиент, исполнение SQL и восстановление после реального падения. Для подтверждения нужны согласованные изолированные среды и отдельные проверки. Локальные fakes и SDK tests не заменяют эти проверки.
Текущие ограничения numeric evidence, relationship utility и live acceptance перечислены в known issues. Они не отменяются passing report или локальным примером. Границы аудита приведены в отчёте.
Помощь
Распространённые ошибки¶
English · Русский
Точные фиксированные сообщения приведены в кавычках кода. Там, где текст зависит от операции/ОС, указан симптом или стабильный JSON error code; это не выдуманный вывод терминала.
| Ошибка / симптом | Причина | Решение |
|---|---|---|
command not found / команда не найдена |
Другое окружение или пакет не установлен | Активируйте нужное окружение; проверьте python -m pip --version и путь команды |
| Версия установленной команды отличается от checkout 1.6.0 | Установленная копия отстаёт от исходников | Установите checkout в отдельное окружение; не выдавайте тест старой копии за тест исходников |
unsafe filesystem path |
Symlink, конфликт входа/выхода или путь за границей | Используйте новую обычную папку; /tmp на macOS — symlink, канонический путь /private/tmp |
Output already exists: |
Пример защищает результат от перезаписи | Выберите новое имя; не удаляйте пользовательский результат |
input_not_found |
Путь относительно другой рабочей папки | Перейдите в корень checkout; проверьте наличие входа без публикации его содержимого |
missing_dependency / код 69 |
Нет optional extra | Установите нужный extra тем же Python; повторите doctor --require-extra |
invalid_arguments |
Не хватает обязательного флага или значение не в диапазоне | Выполните COMMAND --help, задайте count>0, seed≥0, ratio в [0,1] |
configuration |
Нет allowlist, неверный бюджет, конфликт JDBC/component settings | Исправьте конкретный scope/число; не ослабляйте TLS или политику |
external_service |
БД/провайдер недоступен | Проверьте разрешённый endpoint, сеть, TLS, права и квоту через администратора; не печатайте secrets |
Tool arguments failed validation |
MCP-аргументы не соответствуют схеме | Используйте tools/list и типы аргументов; отклонённый payload не пересылайте |
Invalid request parameters |
Некорректный типизированный MCP запрос | Исправьте клиент/SDK и формат JSON-RPC |
Trino request failed |
Безопасно скрытая ошибка backend | Проверьте scope, доступность и бюджеты без раскрытия сообщения драйвера |
| generate вернул 1 и оставил output | Намеренный mixed/negative не прошёл валидацию | Проверьте validation_failed и отчёты expected/observed; не считайте файл успешным valid-набором. |
| validate вернул 1 | Есть нарушения контракта | Прочитайте validation_report; для negative сопоставьте ожидаемые нарушения |
io_failure / код 74 |
Нет прав, места или ошибка файловой системы | Выберите доступный каталог, проверьте диск и резерв, сохраните входы |
recovery_required |
Одобрение прервалось после публикации набора | Прочитайте agent-status; используйте только предложенный agent-recover с проверенным fingerprint |
Что делать при неизвестной ошибке¶
Остановите повторные записи. Сохраните только безопасные метаданные: версию, команду без секретов, код завершения, фазу и счётчики. Воспроизведите на вымышленных входах. Не публикуйте исходный CSV, SQL с литералами, profile/spec своего домена, .env, DSN, полный environment или необработанный traceback.
Далее: пошаговая диагностика, FAQ.
Локальная диагностика¶
Для чего это нужно¶
Проверьте окружение и маленький синтетический пример прежде, чем разбирать подключение к внешнему сервису. Так можно отличить локальную ошибку от сетевой.
Что получится в результате¶
Безопасная сводка версии и локальных возможностей без чтения credentials.
Предварительные требования¶
Открыт терминал в корне checkout, активно нужное окружение; права на временные файлы. Для чтения doctor report не нужен доступ к БД.
Пошаговое выполнение¶
Шаг 1. Сопоставьте пути и версию¶
Что сделать: Покажите путь к интерпретатору и исполняемой команде.
Где выполнить: Терминал, корень checkout.
Команда или пример:
python -c "import sys, shutil; print(sys.executable); print(shutil.which('test-data-agent'))"
test-data-agent --version
Что должно произойти: Видны пути текущего окружения и версия пакета.
Как проверить: Оба пути принадлежат ожидаемому окружению; версия соответствует checkout.
Если не получилось: Если нет, активируйте нужный venv и установите пакет туда. Не печатайте весь environment.
Шаг 2. Запустите локальные проверки¶
Что сделать: Выполните doctor; JSON-режим удобен для автоматизации.
Где выполнить: Тот же терминал.
Команда или пример:
test-data-agent doctor
test-data-agent doctor --json
Что должно произойти: Проверены базовые импорты и smoke generation.
Как проверить: Обе команды возвращают 0.
Если не получилось: Если extra не установлен, установите только нужный; необязательное отсутствие без require-extra не означает поломку базы.
Шаг 3. Проверьте нужное расширение¶
Что сделать: В примере проверяется Parquet; замените его на нужное extra из справки.
Где выполнить: Тот же терминал.
Команда или пример:
test-data-agent doctor --require-extra parquet
Что должно произойти: Проверена локальная работоспособность Parquet, включая временный round trip.
Как проверить: Код 0.
Если не получилось: Установите .[parquet]. Успех для postgres/openai не проверяет сетевой доступ или credentials.
Проверка результата¶
Если doctor проходит, а рабочий вход нет, повторите с вымышленной фикстурой из CSV-инструкции. Если она проходит, проверяйте форму входа, spec и лимиты; при БД отдельно проверяйте разрешённое подключение с администратором.
Типичные ошибки¶
| Ошибка | Причина | Решение |
|---|---|---|
| doctor прошёл, сервис недоступен | Doctor намеренно офлайн | Проверьте сеть/роль/квоту в согласованном сервисном сценарии. |
| Код 70 | Внутренняя ошибка | Составьте минимальный синтетический reproducer; debug не публикуйте без review. |
После прерванного одобрения¶
Выполните test-data-agent agent-status out/ru-agent --json. Если фаза recovery_required, проверьте сохранённые spec/manifest и выполните точную next action из статуса с одобренным SHA-256. agent-recover перепроверяет имеющийся набор и дописывает completion metadata; он не генерирует строки заново. Этот сценарий не воспроизводился вручную в аудите; код и focused tests существуют. Не используйте recover для произвольной повреждённой папки.
Следующий шаг¶
Вопросы и ответы¶
Нужен ли AI? Нет. Демо, CSV, DatasetSpec, детерминированная генерация и валидация работают без provider.
Нужна ли база? Нет. Начните с вымышленного CSV. База — отдельный read-only источник метаданных.
Чем генерация отличается от обезличивания? Генератор создаёт новые значения. Он не переписывает каждую исходную строку и не сохраняет карту исходный ID → новый ID.
Можно ли считать синтетический набор анонимным? Автоматически нельзя. Проверьте spec, разрешённые литералы, редкие комбинации и политику назначения. Система не даёт сертификата статистической анонимности.
Почему статус стал другим после правки spec? Approval относится к точному fingerprint. После правки нужен новый review; старый отпечаток не одобряет новый файл.
Почему один seed не дал прежние байты на другой машине? Помимо seed важны вход, spec и порядок entities в нём, count, mode, locale, версия проекта, зависимости и сериализатор. Сравнивайте в одинаковом записанном окружении.
Где результат? У generate-from-csv --output — файл с соседними артефактами; у generate из spec — папка набора. Manifest указывает условия генерации. См. форматы.
Что означает validation passed? Только выполнение включённых проверок по данному spec. Не доказано, что сам spec описывает все нужные свойства.
Можно ли использовать реальные status? В синтетической генерации — только через отдельный field-scoped local-category после review нечувствительного ограниченного enum и content checks. Разрешение не распространяется на ID, текст, PII, строки или внешний AI. Сохранение ячеек один к одному относится к отдельной mixed-origin трансформации с policy и local receipt; см. ниже.
Можно ли сделать JOIN в profile-query? Нет. Поддерживается ограниченное чтение одной таблицы; не добавляйте обход через unrestricted SQL.
Можно ли импортировать SQL? Проект создаёт SQL-файл. Выполнение — отдельная операция записи в согласованную одноразовую БД с человеческим review. В этом аудите SQL не исполнялся.
Что такое selective transformation? Отдельный публичный opt-in workflow 1.6.0 с policy, snapshot digest и mixed-origin output. CLI и MCP consumers существуют; preservation требует точного локального подтверждения человеком, которое агент выдать не может. См. инструкцию.
Как повторить пример? Используйте новую папку, тот же вход, параметры и окружение. Не применяйте overwrite или удаление предыдущих результатов без необходимости.
Далее: ограничения.
Известные проблемы¶
English · Русский
Stable 1.6.0 прошла публичную проверку. Внешние отзывы сверены с main 22 октября 2026 года; план обработки — English отделяет прежние исправления, текущие ограничения и неподтверждённые наблюдения.
- CSV numeric strings могут выглядеть как телефоны и оставаться sensitive. Не обходите privacy checks и не меняйте exact measures на float ради подавления ошибки. Reviewed numeric profiling планируется; exact decimal generation сохраняет отдельный проверенный контракт --decimal-fields.
- Trino уже поддерживает runtime authentication по проверяемому HTTPS. Для сообщения о внешнем authentication failure нужны configuration/version evidence; fake-driver tests не доказывают работу с конкретным server.
- Numeric shape поддерживает optional zero/subunit frequencies и minimum subunit exponent. В старом профиле evidence может отсутствовать; получите профиль заново. Отрицательный exponent допустим для значений меньше единицы. Отсутствующий Parquet distinct count не означает ноль.
- Validation проверяет объявленные relationships. Пропущенные логические связи, source orphan rates и temporal granularity не подтверждаются одним passing report. Используйте reviewed declarations и явные counts сущностей.
Это направления дальнейшей разработки, а не изменения уже опубликованного wheel 1.6.0. Текущие исправления main и версия выпущенного пакета должны различаться.
Более широкая transformation/session acceptance campaign, включая требуемое настоящее local-terminal preservation acceptance, остаётся открытой. При этом конечный набор вымышленных stable-проверок завершён с записанными пределами; эти два scope нельзя смешивать. Автотесты не доказывают пригодность приватного набора. Provider adapters остаются experimental, resource/artifact durability имеют отдельные ограничения.
Отчёт перевода перечисляет непроверенные здесь сценарии. Исторические исправления и risk dispositions сохранены в Security History — English.