equiframe 0.12.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- equiframe/__init__.py +832 -0
- equiframe/__main__.py +3 -0
- equiframe/_base.py +84 -0
- equiframe/_cli_support.py +125 -0
- equiframe/_comparison_io.py +161 -0
- equiframe/_dataset_provenance.py +146 -0
- equiframe/_decimal.py +22 -0
- equiframe/_diff_capture.py +433 -0
- equiframe/_doctor.py +123 -0
- equiframe/_document_io.py +61 -0
- equiframe/_documents.py +79 -0
- equiframe/_duckdb_transport.py +149 -0
- equiframe/_error_reporting.py +52 -0
- equiframe/_first_use.py +102 -0
- equiframe/_path_compat.py +26 -0
- equiframe/_physical.py +133 -0
- equiframe/_r_review.R +308 -0
- equiframe/_regular_io.py +167 -0
- equiframe/_report_format_v1.py +298 -0
- equiframe/_report_io.py +591 -0
- equiframe/_stability_inventory.py +1421 -0
- equiframe/_timezones.py +257 -0
- equiframe/_vendor/cyclonedx/LICENSE +201 -0
- equiframe/_vendor/cyclonedx/PROVENANCE.md +18 -0
- equiframe/_vendor/cyclonedx/bom-1.6.schema.json +5673 -0
- equiframe/_vendor/cyclonedx/jsf-0.82.schema.json +240 -0
- equiframe/_vendor/cyclonedx/spdx.schema.json +712 -0
- equiframe/adapters.py +454 -0
- equiframe/assertion_types.py +122 -0
- equiframe/assertions.py +271 -0
- equiframe/benchmark.py +101 -0
- equiframe/bundle.py +240 -0
- equiframe/cli.py +693 -0
- equiframe/comparison.py +937 -0
- equiframe/comparison_report.py +660 -0
- equiframe/comparison_types.py +257 -0
- equiframe/compatibility.py +546 -0
- equiframe/contracts.py +879 -0
- equiframe/datasets.py +1301 -0
- equiframe/decision.py +34 -0
- equiframe/destinations.py +295 -0
- equiframe/detector_types.py +431 -0
- equiframe/detectors.py +389 -0
- equiframe/diff.py +192 -0
- equiframe/diff_contracts.py +523 -0
- equiframe/docs/adoption.md +329 -0
- equiframe/docs/api.md +534 -0
- equiframe/docs/arquitecto.md +143 -0
- equiframe/docs/choosing-api.md +84 -0
- equiframe/docs/cientifico.md +180 -0
- equiframe/docs/compatibility.md +254 -0
- equiframe/docs/contributing.md +171 -0
- equiframe/docs/dependencies.md +237 -0
- equiframe/docs/eda.md +166 -0
- equiframe/docs/extending.md +158 -0
- equiframe/docs/fast-ci.md +52 -0
- equiframe/docs/first-use.md +78 -0
- equiframe/docs/index.md +142 -0
- equiframe/docs/ingestion.md +145 -0
- equiframe/docs/inicio.md +129 -0
- equiframe/docs/installed-private.md +97 -0
- equiframe/docs/journeys.md +362 -0
- equiframe/docs/lectura-conversion.md +211 -0
- equiframe/docs/licensing.md +17 -0
- equiframe/docs/maintenance.md +233 -0
- equiframe/docs/migration-ir.md +333 -0
- equiframe/docs/option-audit.md +45 -0
- equiframe/docs/outcome-gates.md +134 -0
- equiframe/docs/performance.md +263 -0
- equiframe/docs/piloto-simulado.md +56 -0
- equiframe/docs/quickstart.md +156 -0
- equiframe/docs/r_review.md +212 -0
- equiframe/docs/recipes.md +248 -0
- equiframe/docs/releasing.md +183 -0
- equiframe/docs/security.md +218 -0
- equiframe/docs/semantics.md +274 -0
- equiframe/docs/sqlite-snapshots.md +262 -0
- equiframe/docs/universal-sources.md +49 -0
- equiframe/docs/universalidad-cinco-pasos.md +107 -0
- equiframe/docs/upgrading.md +538 -0
- equiframe/duckdb_capture.py +410 -0
- equiframe/eda/__init__.py +36 -0
- equiframe/eda/__main__.py +3 -0
- equiframe/eda/_backend.py +612 -0
- equiframe/eda/_inventory.py +49 -0
- equiframe/eda/_paths.py +49 -0
- equiframe/eda/_report.py +291 -0
- equiframe/eda/api.py +535 -0
- equiframe/eda/cli.py +102 -0
- equiframe/eda/models.py +239 -0
- equiframe/errors.py +83 -0
- equiframe/evidence.py +375 -0
- equiframe/examples/integrations/eda_generic.py +60 -0
- equiframe/examples/integrations/outcome_gates.py +94 -0
- equiframe/examples/integrations/sqlite_snapshot.py +246 -0
- equiframe/examples/integrations/sqlite_snapshot_demo.py +226 -0
- equiframe/examples/integrations/universal_first_use.py +296 -0
- equiframe/examples/journeys/README.md +31 -0
- equiframe/examples/journeys/__init__.py +1 -0
- equiframe/examples/journeys/a_pandas_refactor.py +88 -0
- equiframe/examples/journeys/b_native_migration.py +181 -0
- equiframe/examples/journeys/c_retail_etl.py +460 -0
- equiframe/examples/journeys/common.py +136 -0
- equiframe/examples/journeys/d_financial_reconciliation.py +96 -0
- equiframe/examples/journeys/e_telemetry.py +135 -0
- equiframe/examples/journeys/f_data_science_preparation.py +84 -0
- equiframe/examples/journeys/g_external_snapshots.py +197 -0
- equiframe/examples/journeys/h_portable_ci.py +129 -0
- equiframe/examples/journeys/requirements.lock +249 -0
- equiframe/examples/journeys/verify_journeys.py +117 -0
- equiframe/examples/load_convert_compare.py +85 -0
- equiframe/execution.py +355 -0
- equiframe/execution_types.py +177 -0
- equiframe/ingestion.py +744 -0
- equiframe/local.py +126 -0
- equiframe/migration/__init__.py +94 -0
- equiframe/migration/_physical.py +8 -0
- equiframe/migration/backends/_timestamp_transport.py +109 -0
- equiframe/migration/backends/duckdb.py +651 -0
- equiframe/migration/backends/duckdb_decimal.py +125 -0
- equiframe/migration/backends/duckdb_time.py +87 -0
- equiframe/migration/backends/pandas.py +544 -0
- equiframe/migration/backends/polars.py +915 -0
- equiframe/migration/backends/polars_decimal.py +231 -0
- equiframe/migration/io.py +198 -0
- equiframe/migration/ports.py +96 -0
- equiframe/migration/runner.py +545 -0
- equiframe/migration/runner_types.py +405 -0
- equiframe/migration/types.py +354 -0
- equiframe/migration/validation.py +619 -0
- equiframe/normalization.py +358 -0
- equiframe/pipeline.py +274 -0
- equiframe/pipeline_types.py +247 -0
- equiframe/ports.py +39 -0
- equiframe/preprocessing.py +110 -0
- equiframe/profile_types.py +343 -0
- equiframe/profiles.py +447 -0
- equiframe/py.typed +0 -0
- equiframe/r_review.py +706 -0
- equiframe/reduction.py +518 -0
- equiframe/registry.py +121 -0
- equiframe/report_rendering.py +366 -0
- equiframe/report_types.py +294 -0
- equiframe/reporting.py +26 -0
- equiframe/rule_types.py +178 -0
- equiframe/rules.py +819 -0
- equiframe/schemas/r-execution-binding-1.0.schema.json +46 -0
- equiframe/schemas/r-review-binding-1.0.schema.json +28 -0
- equiframe/schemas/r-review-options-1.0.schema.json +38 -0
- equiframe/schemas/r-review-result-1.0.schema.json +207 -0
- equiframe/schemas/reviewed-decision-1.0.schema.json +3394 -0
- equiframe/serialization.py +152 -0
- equiframe/snapshot.py +296 -0
- equiframe/sources.py +283 -0
- equiframe/tables.py +459 -0
- equiframe/types.py +71 -0
- equiframe/values.py +252 -0
- equiframe/verification_request.py +35 -0
- equiframe/verify.py +799 -0
- equiframe/verify_types.py +255 -0
- equiframe/workflow.py +510 -0
- equiframe/workflow_request.py +38 -0
- equiframe-0.12.4.dist-info/METADATA +268 -0
- equiframe-0.12.4.dist-info/RECORD +170 -0
- equiframe-0.12.4.dist-info/WHEEL +4 -0
- equiframe-0.12.4.dist-info/entry_points.txt +3 -0
- equiframe-0.12.4.dist-info/licenses/LICENSE +21 -0
- equiframe-0.12.4.dist-info/licenses/THIRD_PARTY_NOTICES.md +42 -0
- equiframe-0.12.4.dist-info/licenses/tools/cyclonedx/LICENSE +201 -0
- equiframe-0.12.4.dist-info/licenses/tools/cyclonedx/PROVENANCE.md +18 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Lectura de archivos y conversión de DataFrames
|
|
2
|
+
|
|
3
|
+
La API `load_dataset`, incluida en el alcance estable de 0.12.0, lee un archivo local, descubre su estructura
|
|
4
|
+
y crea un **DataFrame real de Pandas**. Si se selecciona Polars o DuckDB,
|
|
5
|
+
convierte ese mismo DataFrame y entrega el objeto nativo correspondiente.
|
|
6
|
+
Esta ruta convierte datos; no traduce un programa ni ejecuta transformaciones
|
|
7
|
+
independientes en tres motores. Tampoco entrena detectores ni ejecuta R.
|
|
8
|
+
|
|
9
|
+
La implementación se añadió el 26 de octubre de 2026. Su estabilización protege
|
|
10
|
+
la interfaz, las conversiones admitidas y sus errores; no promete todas las
|
|
11
|
+
variantes de cada formato o combinación de dependencias. La
|
|
12
|
+
[compatibilidad](compatibility.md) identifica las verificaciones ejecutadas y
|
|
13
|
+
sus límites, sin atribuirlas a otros artefactos.
|
|
14
|
+
|
|
15
|
+
## Uso desde Python
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
import equiframe as ef
|
|
19
|
+
|
|
20
|
+
datos = ef.load_dataset("ventas.json")
|
|
21
|
+
pandas_df = datos.pandas
|
|
22
|
+
print(datos.info.to_dict()) # columnas, tipos observados, nulos, NaN y número de filas
|
|
23
|
+
|
|
24
|
+
polars_datos = ef.convert_dataset(datos, target="polars")
|
|
25
|
+
polars_df = polars_datos.frame
|
|
26
|
+
|
|
27
|
+
# Las conversiones encadenadas consumen el objeto nativo actual.
|
|
28
|
+
with ef.convert_dataset(polars_datos, target="duckdb") as duckdb_datos:
|
|
29
|
+
pandas_de_vuelta = ef.convert_dataset(duckdb_datos, target="pandas")
|
|
30
|
+
|
|
31
|
+
# También puede seleccionarse el destino en la misma llamada.
|
|
32
|
+
with ef.load_dataset("ventas.parquet", target="duckdb") as datos_sql:
|
|
33
|
+
relacion = datos_sql.frame
|
|
34
|
+
resultado = relacion.limit(10).df()
|
|
35
|
+
# La relación DuckDB depende de la conexión privada, cerrada al salir del with.
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`DatasetResult.pandas` conserva el DataFrame de origen y `frame` contiene el
|
|
39
|
+
objeto del destino seleccionado: DataFrame de Pandas, DataFrame de Polars o
|
|
40
|
+
DuckDBPyRelation. `close()` libera la conexión DuckDB que pertenece al resultado;
|
|
41
|
+
no abre archivos DuckDB compartidos. El usuario puede trabajar con esos objetos
|
|
42
|
+
mediante las APIs de sus motores. `inspect_dataset(path)` devuelve solamente
|
|
43
|
+
`DatasetInfo`, pero realiza la lectura completa dentro de los límites declarados.
|
|
44
|
+
|
|
45
|
+
## Identidad de la fuente y de la conversión
|
|
46
|
+
|
|
47
|
+
Cada lectura utiliza una única captura de los bytes del archivo y devuelve
|
|
48
|
+
`DatasetResult.provenance`, también accesible desde `info.provenance`.
|
|
49
|
+
`DatasetSource` identifica URI, formato, SHA-256 y tamaño de esos bytes; conserva
|
|
50
|
+
las opciones efectivas en `read_options_json`, consultables como un objeto con
|
|
51
|
+
la propiedad `read_options`. Esto incluye la hoja, el delimitador o el modo de
|
|
52
|
+
texto resueltos durante la lectura, no solamente las opciones iniciales.
|
|
53
|
+
|
|
54
|
+
`DatasetProvenance` vincula esa fuente con `pandas_sha256`, el destino `target`
|
|
55
|
+
y `target_sha256`. Las conversiones admiten las seis direcciones entre Pandas,
|
|
56
|
+
Polars y DuckDB; leen el objeto nativo seleccionado, sin releer el archivo ni
|
|
57
|
+
sustituirlo por una copia anterior. La conversión rechaza una modificación del
|
|
58
|
+
objeto nativo o del Pandas original posterior a la captura. El esquema nativo
|
|
59
|
+
de Polars o DuckDB se verifica antes de convertir a Arrow; una exportación Arrow
|
|
60
|
+
coincidente no sustituye esa comprobación de tipos. La exportación del origen
|
|
61
|
+
también rechaza una modificación del Pandas original. Para trabajar sobre datos modificados,
|
|
62
|
+
el consumidor debe establecer una nueva entrada y su identidad, sin reutilizar
|
|
63
|
+
la procedencia original como si describiera esos cambios.
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
print(datos.provenance.source.sha256)
|
|
67
|
+
print(datos.provenance.source.read_options)
|
|
68
|
+
print(datos.info.to_dict(include_provenance=True))
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`info.to_dict()` omite esa procedencia por defecto, porque su URI puede contener
|
|
72
|
+
una ruta privada. `include_provenance=True` la añade explícitamente;
|
|
73
|
+
`include_metadata=True` controla por separado los metadatos originales.
|
|
74
|
+
Estas huellas identifican los datos y opciones observados; no autentican al
|
|
75
|
+
productor del archivo ni aprueban una migración de programas.
|
|
76
|
+
|
|
77
|
+
## Formatos y decisiones que puede requerir el lector
|
|
78
|
+
|
|
79
|
+
| Archivo | Representación y opciones |
|
|
80
|
+
|---|---|
|
|
81
|
+
| JSON | Un objeto de registro o una lista de registros. Los escalares y listas de valores se conservan en una columna `value`, sin aplanar sus objetos o arrays. Los números fraccionarios se leen como `Decimal`. Para un contenedor de registros se exige `records_path`, sin expandir otras colecciones. |
|
|
82
|
+
| JSONL / NDJSON | Un registro o valor por línea no vacía. Se rechazan miembros JSON duplicados, NaN e Infinity no estándar. |
|
|
83
|
+
| CSV | Detecta delimitadores consistentes entre coma, punto y coma, tabulación y barra vertical. Si más de uno encaja, solicita elección. Por defecto la primera fila es el encabezado. |
|
|
84
|
+
| TXT / TSV | Texto libre: una columna `text`, una fila por línea. Si también puede interpretarse como tabla, pregunta `lines` o `delimited`. Se puede fijar `delimiter`, `header` y `text_mode`. No se inventa un esquema para texto libre. |
|
|
85
|
+
| Excel | `.xlsx` y `.xlsm` mediante openpyxl; `.xls` mediante xlrd. Selecciona automáticamente solo cuando hay una hoja. Con varias hojas exige `sheet`. Lee las filas/celdas observadas sin truncarlas según dimensiones declaradas por el productor. No ejecuta macros; XLSX/XLSM con fórmulas o errores exige un archivo con valores. |
|
|
86
|
+
| XML | Usa defusedxml y rechaza DTD, entidades y referencias externas. Conserva atributos, campos y elementos repetidos; `records_path` permite seleccionar registros. El XML de contenido mixto que no pueda representarse fielmente se rechaza. |
|
|
87
|
+
| Parquet | Conserva tipos Arrow, unidades, zonas y máscaras de ausencia al construir Pandas con ArrowDtype. |
|
|
88
|
+
| GeoJSON | FeatureCollection, Feature y geometrías. Conserva `geometry` y `properties` originales; expone además `properties.nombre` y los otros miembros como `feature.nombre`. Los metadatos de la colección quedan en `info.metadata`. No requiere GIS ni cambia el sistema de coordenadas. |
|
|
89
|
+
|
|
90
|
+
Ejemplos de desambiguación:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
opciones = ef.DatasetReadOptions(sheet="Ventas")
|
|
94
|
+
datos = ef.load_dataset("libro.xlsx", options=opciones, target="polars")
|
|
95
|
+
|
|
96
|
+
opciones = ef.DatasetReadOptions(records_path="/respuesta/ventas")
|
|
97
|
+
datos = ef.load_dataset("respuesta.json", options=opciones)
|
|
98
|
+
|
|
99
|
+
opciones = ef.DatasetReadOptions(delimiter="\t", header=False)
|
|
100
|
+
datos = ef.load_dataset("mediciones.txt", options=opciones)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
En JSON `records_path` es un JSON Pointer RFC 6901. En XML es una ruta de
|
|
104
|
+
elementos de ElementTree, por ejemplo `./ventas/venta` o `.//venta`.
|
|
105
|
+
No se descargan esquemas, no se ejecuta XPath arbitrario ni se evalúa código.
|
|
106
|
+
|
|
107
|
+
## Tipos y preservación
|
|
108
|
+
|
|
109
|
+
La inferencia textual es conservadora: enteros canónicos se convierten en
|
|
110
|
+
enteros y números decimales inequívocos se convierten en `Decimal`, sin pasar
|
|
111
|
+
por float. Los ceros iniciales, espacios, representaciones mezcladas y fechas
|
|
112
|
+
permanecen como texto. Un campo vacío sigue siendo una cadena vacía; no se
|
|
113
|
+
interpreta automáticamente como nulo ni se adivinan tokens como `NA`.
|
|
114
|
+
Los números ya almacenados por Excel tienen la precisión que conserva el
|
|
115
|
+
libro; no se recuperan dígitos perdidos antes de llegar a EquiFrame. Los formatos
|
|
116
|
+
Excel de enteros con ceros de relleno, como `000000`, se conservan como texto y
|
|
117
|
+
se informa esa decisión. Las fechas tipadas de Excel conservan su tipo.
|
|
118
|
+
XLS expone valores almacenados o cacheados; su lector no identifica
|
|
119
|
+
independientemente todas las fórmulas del archivo heredado.
|
|
120
|
+
|
|
121
|
+
`DatasetInfo.notes` informa las inferencias. Para conservar todo texto o
|
|
122
|
+
declarar unas pocas columnas:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
opciones = ef.DatasetReadOptions(
|
|
126
|
+
infer_text_types=False,
|
|
127
|
+
column_types={"importe": "decimal", "cantidad": "integer", "codigo": "string"},
|
|
128
|
+
)
|
|
129
|
+
datos = ef.load_dataset("ventas.csv", options=opciones)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Tipos explícitos admitidos: `string`, `integer`, `decimal`, `boolean` y `json`.
|
|
133
|
+
`json` conserva un objeto o array como texto JSON sin convertir sus Decimal a
|
|
134
|
+
float. Es una representación explícita útil para geometrías heterogéneas o
|
|
135
|
+
propiedades anidadas que no admitan una única estructura Arrow:
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
opciones = ef.DatasetReadOptions(column_types={"geometry": "json", "properties": "json"})
|
|
139
|
+
datos = ef.load_dataset("mapa.geojson", options=opciones, target="polars")
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
No se cambia automáticamente a texto cuando un motor no admite un tipo.
|
|
143
|
+
La ruta de conversión comprueba la representación Arrow inicial y recorre por
|
|
144
|
+
completo el resultado nativo para rechazar cambios de contenido, nulos/NaN,
|
|
145
|
+
orden, precisión, escala o zona temporal. Permite cambios de transporte como
|
|
146
|
+
`string` a `large_string` que conservan los valores. Un tipo incompatible genera
|
|
147
|
+
`CapabilityError`; el resultado no se declara equivalente ni se normaliza.
|
|
148
|
+
|
|
149
|
+
Los campos JSON ausentes se materializan como nulos en las columnas unificadas;
|
|
150
|
+
sus posiciones originales quedan en `info.metadata["absent_json_members_by_row"]`.
|
|
151
|
+
`info.to_dict()` omite metadatos originales por defecto; use
|
|
152
|
+
`info.to_dict(include_metadata=True)` cuando quiera incluirlos explícitamente.
|
|
153
|
+
Los metadatos de una colección GeoJSON pueden contener información del usuario.
|
|
154
|
+
|
|
155
|
+
## Un comando para leer y elegir destino
|
|
156
|
+
|
|
157
|
+
```console
|
|
158
|
+
equiframe dataset load ventas.json
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
La misma invocación muestra la estructura, pregunta las ambigüedades del archivo
|
|
162
|
+
y pregunta: «¿A qué motor quiere migrar desde Pandas? pandas / polars / duckdb».
|
|
163
|
+
Para scripts y entradas no interactivas se pasa el destino:
|
|
164
|
+
|
|
165
|
+
```console
|
|
166
|
+
equiframe dataset load ventas.json --target polars
|
|
167
|
+
equiframe dataset load libro.xlsx --sheet Ventas --target duckdb
|
|
168
|
+
equiframe dataset load ventas.csv --target polars --output copia.parquet
|
|
169
|
+
equiframe dataset inspect mapa.geojson
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Opciones de lectura: `--format`, `--sheet`, `--records-path`, `--delimiter`
|
|
173
|
+
(`tab` significa tabulación), `--header/--no-header`, `--text-mode`,
|
|
174
|
+
`--infer-types/--keep-text`, `--encoding`, `--max-bytes` y `--max-rows`.
|
|
175
|
+
Sin `--output`, el objeto convertido existe durante el comando; en Python
|
|
176
|
+
la API devuelve el objeto para continuar trabajando. `--output` y
|
|
177
|
+
`DatasetResult.to_parquet()` exportan el **Pandas original cargado** a un Parquet
|
|
178
|
+
nuevo; no exportan transformaciones que el usuario aplique después a `frame`.
|
|
179
|
+
La exportación escribe y sincroniza primero un temporal hermano, y publica
|
|
180
|
+
exclusivamente el archivo completo mediante un enlace duro en el mismo sistema
|
|
181
|
+
de archivos. El destino no se sobrescribe. Si el sistema no admite esa operación,
|
|
182
|
+
la exportación falla; no usa una copia parcial como alternativa. El temporal
|
|
183
|
+
propio se retira al terminar. No se promete durabilidad ante corte de energía.
|
|
184
|
+
Un error posterior a la publicación puede dejar el Parquet completo visible;
|
|
185
|
+
inspeccione y compruebe su contenido antes de decidir una recuperación, sin
|
|
186
|
+
suponer que cualquier archivo existente pertenece al intento fallido.
|
|
187
|
+
La conversión no equivale a una comparación
|
|
188
|
+
semántica de dos implementaciones; para esa tarea siguen disponibles `diff`
|
|
189
|
+
y los contratos de equivalencia.
|
|
190
|
+
|
|
191
|
+
Los fallos CLI conservan el código estable en la primera línea de stderr y la
|
|
192
|
+
guía fija `hint[...]` después. Un `DatasetChoiceRequired` puede añadir entonces
|
|
193
|
+
un objeto JSON con `required_option` y `choices` para resolver una ambigüedad.
|
|
194
|
+
Un error de lectura/configuración termina con código 2; dependencias no
|
|
195
|
+
disponibles y fallos técnicos terminan con código 3. El código 0 sólo indica que
|
|
196
|
+
se completó la lectura y conversión solicitadas, sin aprobar equivalencia.
|
|
197
|
+
|
|
198
|
+
## Dependencias y límites
|
|
199
|
+
|
|
200
|
+
El extra `files` añade Pandas, Arrow, openpyxl, xlrd y defusedxml. Polars y DuckDB
|
|
201
|
+
se seleccionan mediante sus extras existentes. Los lectores y motores se importan
|
|
202
|
+
solo al usarlos; un extra faltante produce `MissingDependencyError` con la
|
|
203
|
+
dependencia necesaria. No hay instalaciones automáticas.
|
|
204
|
+
|
|
205
|
+
Por defecto se admiten hasta 128 MiB de archivo, un millón de filas y dos
|
|
206
|
+
millones de celdas. Son límites de admisión; no son cuotas duras de RAM ni de
|
|
207
|
+
descompresión. La lectura es local y completa, no distribuida ni en streaming.
|
|
208
|
+
Las rutas locales pueden seguir enlaces simbólicos; el llamante debe elegir
|
|
209
|
+
archivos y directorios de confianza. Se rechazan nombres de columnas duplicados,
|
|
210
|
+
filas CSV irregulares y conversiones sin representación fiel. No se infieren
|
|
211
|
+
claves de negocio, monedas, fechas, CRS ni reglas de aceptación del proyecto.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# License
|
|
2
|
+
|
|
3
|
+
The owner selected MIT on 2026-10-27 for the original EquiFrame and EquiFrame
|
|
4
|
+
Benchmark code and accompanying project documentation, examples and tools.
|
|
5
|
+
Copyright (c) 2026 Hernán Troya. Each distribution carries the full LICENSE.
|
|
6
|
+
|
|
7
|
+
MIT permits use, modification, commercial use and redistribution under its
|
|
8
|
+
terms, including preservation of the copyright and permission notice. The
|
|
9
|
+
software is provided without warranty as stated in the license.
|
|
10
|
+
|
|
11
|
+
Third-party material keeps its existing license. Both core distributions
|
|
12
|
+
include unmodified CycloneDX schemas under Apache-2.0; their upstream license,
|
|
13
|
+
provenance and notices are preserved. See THIRD_PARTY_NOTICES.md in the package.
|
|
14
|
+
|
|
15
|
+
This decision does not relicense downloaded datasets, the thesis manuscript,
|
|
16
|
+
external dependencies or separately owned components. Publication remains a
|
|
17
|
+
separate owner-authorized task.
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Maintenance, support and trust incidents
|
|
2
|
+
|
|
3
|
+
[Handbook](index.md) · [Adoption](adoption.md) · [Compatibility](compatibility.md) ·
|
|
4
|
+
[Upgrading](upgrading.md) · [Security](security.md) · [Release/rollback](releasing.md)
|
|
5
|
+
|
|
6
|
+
## Maintainer and best-effort support
|
|
7
|
+
|
|
8
|
+
The project owner has assigned **Hernán Troya (`htroya`)**
|
|
9
|
+
responsibility for maintenance, releases and security coordination. This is
|
|
10
|
+
best-effort maintenance by one owner, not a staffed service or support contract.
|
|
11
|
+
No backup, on-call coverage, numeric response deadline or SLA is promised.
|
|
12
|
+
|
|
13
|
+
| Role | Scope | Named owner | Backup |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| Core | Comparison/contracts, typed states, assertions, evidence integrity and historical readers | Hernán Troya (`htroya`) | Not designated |
|
|
16
|
+
| Adapters | Native capture/execution, capabilities, dependencies and measured matrix cells | Hernán Troya (`htroya`) | Not designated |
|
|
17
|
+
| Documentation | Installation, diagnosis, migration guidance and reproducible examples | Hernán Troya (`htroya`) | Not designated |
|
|
18
|
+
| Releases | Exact-byte checks, manual publication/withdrawal and recovery | Hernán Troya (`htroya`) | Not designated |
|
|
19
|
+
| Security | Private intake, exposure review and vulnerability coordination | Hernán Troya (`htroya`) | Not designated |
|
|
20
|
+
|
|
21
|
+
The core remains independent of a service, domain schema and infrastructure.
|
|
22
|
+
Service/DW ownership, concurrency, authorization and aggregate quotas stay with
|
|
23
|
+
those components' owners; an adapter issue does not authorize redesigning them.
|
|
24
|
+
Keep experimental benchmark/scientific acceptance distinct from operational
|
|
25
|
+
comparison maintenance.
|
|
26
|
+
|
|
27
|
+
## Report a problem
|
|
28
|
+
|
|
29
|
+
Use [the public issue channel](https://github.com/htroya/equiframe/issues)
|
|
30
|
+
for nonsensitive bugs and minimal synthetic reproductions. Use
|
|
31
|
+
[private vulnerability reporting](https://github.com/htroya/equiframe/security/advisories/new)
|
|
32
|
+
for sensitive security reports. Both routes belong to the project's single
|
|
33
|
+
public repository. For each release, the maintainer must enable both routes
|
|
34
|
+
and verify their availability. If private intake cannot be verified, retain
|
|
35
|
+
sensitive details locally until confidential intake can be arranged; do not
|
|
36
|
+
move them to a public issue.
|
|
37
|
+
|
|
38
|
+
Do not put credentials, real data, personal information or sensitive exploit
|
|
39
|
+
details in a public issue, an ordinary issue with a broader audience, or a
|
|
40
|
+
guessed email address. A repository issue is not automatically a private
|
|
41
|
+
security channel. If a safe route cannot be verified, retain sensitive details
|
|
42
|
+
locally and stop using the affected acceptance path.
|
|
43
|
+
|
|
44
|
+
Provide only the minimal permitted reproduction:
|
|
45
|
+
|
|
46
|
+
1. Classify installation, comprehension, semantics, integration, performance
|
|
47
|
+
and/or evidence; state impact and whether false `equivalent` is suspected
|
|
48
|
+
2. Identify exact package/commit, wheel/sdist and dependency-lock hashes, Python,
|
|
49
|
+
OS/architecture, engine versions and selected extras. Redact account/path data
|
|
50
|
+
3. Give a small synthetic fixture and trusted code/SQL that someone can inspect
|
|
51
|
+
before executing. Include the contract, relevant policy, budgets and explicit
|
|
52
|
+
reproduction commands; do not upload a complete private run or environment
|
|
53
|
+
4. State independently expected versus observed state, completeness, acceptance
|
|
54
|
+
and exit code. Explain the expected-output provenance. Separate engine
|
|
55
|
+
agreement from correctness and report integrity from semantic acceptance
|
|
56
|
+
5. Attach only a reviewed minimized report when permitted, with its inventory
|
|
57
|
+
verification outcome and hash. Mark missing/partial evidence explicitly
|
|
58
|
+
6. Identify the last known-good **artifact**, if known, repeatability and any safe
|
|
59
|
+
workaround. Preserve earlier failures; do not silently replace the baseline
|
|
60
|
+
|
|
61
|
+
The [adoption guide](adoption.md) describes consent and minimal observation.
|
|
62
|
+
Permission to participate does not authorize sharing the person's data or posting
|
|
63
|
+
to an issue. Do not request additional private data until its necessity, recipient
|
|
64
|
+
and handling have been agreed. Raw exception causes can reveal more than the
|
|
65
|
+
ordinary report; inspect diagnostics before sending them.
|
|
66
|
+
|
|
67
|
+
## Triage priorities without response deadlines
|
|
68
|
+
|
|
69
|
+
The maintainer uses the following best-effort triage order. It does not establish
|
|
70
|
+
staffed coverage, response deadlines or a service guarantee.
|
|
71
|
+
|
|
72
|
+
| Priority | Examples | Triage goal |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| P0: critical trust incident | Suspected false `equivalent`, acceptance of incomplete/invalid evidence, or material disclosure/integrity risk | Stop relying on the affected claim, preserve evidence and seek owner-led containment/escalation before restoring acceptance |
|
|
75
|
+
| P1: blocking defect | Reproducible installation/integration failure, documented supported case incorrectly rejected, or an unusable evidence reader | Establish scope and a safe workaround, then reproduce and verify a focused correction |
|
|
76
|
+
| P2: nonblocking friction | Comprehension gaps, minor diagnosis problems, performance outside an unpromised target | Preserve observations, assess impact and prioritize repeated real pain without weakening semantics |
|
|
77
|
+
| P3: capability proposal | New engine, integration or unsupported representation | Require repeated real need, ownership, corpus, budget and an explicit support decision before implementation commitment |
|
|
78
|
+
|
|
79
|
+
Category and severity are separate. A semantics report is not automatically a
|
|
80
|
+
confirmed defect; an evidence issue may be critical. Safe `not_evaluable` is
|
|
81
|
+
not false equivalence. If the owner is unavailable, leave the issue pending;
|
|
82
|
+
there is no designated backup or automatic escalation promise. Do not promise a
|
|
83
|
+
reply or reopen a potentially unsafe path merely because time has passed.
|
|
84
|
+
|
|
85
|
+
## Reproduce, correct and reconfirm
|
|
86
|
+
|
|
87
|
+
Use a local incident/issue record with source evidence, scope, category, proposed
|
|
88
|
+
priority, triage decision, assigned owner when accepted, correction and validation
|
|
89
|
+
references. Keep review, release approval and consumer confirmation separately
|
|
90
|
+
pending. A suggested workflow is: reported, scoped, reproduced or needs evidence,
|
|
91
|
+
correction under review, technically verified, awaiting consumer reconfirmation,
|
|
92
|
+
then resolved. Unsupported, duplicate or withdrawn reports need an explicit
|
|
93
|
+
rationale; do not erase the original observation.
|
|
94
|
+
|
|
95
|
+
For a reproducible defect:
|
|
96
|
+
|
|
97
|
+
1. Preserve the failing artifact, permitted evidence and independent expectation.
|
|
98
|
+
Reduce a copy to a minimal synthetic case while retaining the same failure
|
|
99
|
+
2. Add a regression that fails against the affected version for the stated reason.
|
|
100
|
+
Include relevant equivalent, different, invalid and incomplete cases; tests
|
|
101
|
+
derived only from the implementation can confirm the same error
|
|
102
|
+
3. Make a narrow correction with review of API/format/adapter/contract impacts.
|
|
103
|
+
Do not rename a stable surface experimental to evade compatibility duties
|
|
104
|
+
4. Run affected semantic and historical-reader tests, full candidate checks,
|
|
105
|
+
outside-checkout installed recipes and affected compatibility matrix cells
|
|
106
|
+
against new immutable bytes. Record failed, blocked and unexecuted checks
|
|
107
|
+
5. Document scope, behavior changes, migration, exact hashes and residual limits.
|
|
108
|
+
Follow [release approval](releasing.md); technical verification does not
|
|
109
|
+
authorize distribution, a public issue, dependency access or a remote CI run
|
|
110
|
+
6. Through the authorized channel, ask the affected consumer to test the original
|
|
111
|
+
use case and the relevant later real change with the identified correction.
|
|
112
|
+
Record whether the integration is retained and reporting/updating is understood
|
|
113
|
+
7. Mark consumer reconfirmation only after their actual response and evidence.
|
|
114
|
+
If they cannot repeat it, keep that gap open rather than treating internal tests
|
|
115
|
+
as their approval. Reopen the issue if their case still fails
|
|
116
|
+
|
|
117
|
+
Track actual triage/reproduction/review/documentation effort and unresolved work.
|
|
118
|
+
Sustainable support needs observed capacity and accepted owners, not estimates
|
|
119
|
+
presented as delivered service.
|
|
120
|
+
|
|
121
|
+
## False `equivalent`: critical trust incident procedure
|
|
122
|
+
|
|
123
|
+
A plausible false-equivalence report triggers precautionary containment while
|
|
124
|
+
validation proceeds. This means the evaluated contract admitted a difference or
|
|
125
|
+
invalid/incomplete evaluation as acceptance; a deliberate permissive contract or
|
|
126
|
+
two engines sharing the same bug needs separate diagnosis. Do not dismiss the
|
|
127
|
+
report merely because existing tests pass or a manifest has valid hashes.
|
|
128
|
+
|
|
129
|
+
1. **Contain.** Stop using the suspect result/path as an acceptance gate. Preserve
|
|
130
|
+
original artifacts and private evidence; suspend distribution/recommendation
|
|
131
|
+
of affected candidate hashes within the authorized scope. Do not silently
|
|
132
|
+
weaken a contract, remove the check or convert `not_evaluable` to success
|
|
133
|
+
2. **Escalate safely.** Seek an accepted incident owner and relevant core/adapter,
|
|
134
|
+
release and security reviewers through verified routes. Keep sensitive details
|
|
135
|
+
restricted. No staffed response or automatic external notification is implied
|
|
136
|
+
3. **Bound impact.** Identify affected package commits and wheel hashes, exact
|
|
137
|
+
dependency versions, APIs, adapter stages, data types, contract revisions and
|
|
138
|
+
policies, output/evidence formats and environments. Distinguish confirmed,
|
|
139
|
+
possibly affected and untested scopes; inventory downstream decisions that
|
|
140
|
+
relied on the suspect result without uploading their raw data
|
|
141
|
+
4. **Reproduce independently.** Build the smallest permitted case with an expected
|
|
142
|
+
result reviewed independently of the failing path. Compare the identified
|
|
143
|
+
previous and current artifacts; keep counterexamples and original decisions
|
|
144
|
+
5. **Correct and verify.** Add the failing regression, repair the narrow cause and
|
|
145
|
+
exercise adjacent policies, all affected native adapters, interruption/limits,
|
|
146
|
+
invalid expected inputs and persisted readers. Re-run full affected source,
|
|
147
|
+
distribution and compatibility gates. A fail-closed fix may reject formerly
|
|
148
|
+
accepted input immediately; explain that boundary explicitly
|
|
149
|
+
6. **Prepare safe recovery.** Supply a new approved artifact with exact pins,
|
|
150
|
+
change notes and validation evidence. Test upgrade in an isolated environment
|
|
151
|
+
and re-evaluate affected consumer cases. Roll back only to a demonstrated
|
|
152
|
+
known-safe artifact/environment; if none exists, suspend acceptance. Never
|
|
153
|
+
rewrite historic evidence or downgrade format markers to force readability
|
|
154
|
+
7. **Notify with approval.** The owner approves the recipient scope, channel and
|
|
155
|
+
consequential content before an affected-user notice is sent. Explain affected
|
|
156
|
+
and uncertain versions/contracts/adapters, impact, containment, safe upgrade
|
|
157
|
+
or rollback and cases requiring re-evaluation. Reach only authorized recipients
|
|
158
|
+
through verified channels and share no other consumer's private data. Record
|
|
159
|
+
actual dispatch/acknowledgment separately from a prepared draft
|
|
160
|
+
8. **Reconfirm and close.** Obtain affected-consumer confirmation on their original
|
|
161
|
+
and later-change cases, record any downstream corrective decision, and document
|
|
162
|
+
residual exposure. Keep unreached consumers and unverified environments open.
|
|
163
|
+
Owner review closes containment only with evidence; a green internal suite
|
|
164
|
+
alone does not close the trust incident
|
|
165
|
+
|
|
166
|
+
For a future public release, advisory and index actions require the owner's
|
|
167
|
+
separate approval. A yank does not remove installed or exactly pinned copies.
|
|
168
|
+
Published artifacts must not be overwritten. Before a first registry publication
|
|
169
|
+
there is no public release to withdraw; afterwards use the same identified-byte
|
|
170
|
+
withdrawal/recovery process in [releasing](releasing.md).
|
|
171
|
+
|
|
172
|
+
## Upgrade, dependency and support decisions
|
|
173
|
+
|
|
174
|
+
Preserve package version, contract revision and evidence format as separate
|
|
175
|
+
identities. Follow the [compatibility policy](compatibility.md), including its
|
|
176
|
+
deprecation window and fail-closed exception, and [upgrade checks](upgrading.md).
|
|
177
|
+
New evidence must not change the meaning of historical records. Unknown formats
|
|
178
|
+
remain rejected; migration needs explicit review and new traceable artifacts.
|
|
179
|
+
|
|
180
|
+
Support claims must cite exact measured cells. The current maturity plan requires
|
|
181
|
+
Python 3.10/3.11/3.12/3.13 with per-interpreter first-use closures and explicit
|
|
182
|
+
platform receipts. Do not expand support from metadata, configured but unexecuted CI, or past results
|
|
183
|
+
for different candidate hashes. Dependency changes require fresh affected-cell
|
|
184
|
+
validation and updated artifact-bound inventories; timestamps and old advisory
|
|
185
|
+
receipts cannot certify changed dependencies.
|
|
186
|
+
|
|
187
|
+
The retained STEP9 minimum-profile advisory match for **CVE-2026-25087** remains
|
|
188
|
+
visible. The recorded advisory states the affected Arrow C++ functionality is
|
|
189
|
+
not exposed through Python bindings, which are excluded from vulnerability;
|
|
190
|
+
this does not turn the retained package-version match into a clean scan, prove
|
|
191
|
+
all native dependencies safe or complete the source-security assessment.
|
|
192
|
+
That historical result does not substitute for triage of the dependencies in a
|
|
193
|
+
new release. See [dependency evidence](dependencies.md) and current release gates.
|
|
194
|
+
|
|
195
|
+
The earlier stopped source-security assessment remains historical and is not
|
|
196
|
+
relabeled as a pass. The owner has now authorized stable-release preparation and
|
|
197
|
+
manual TestPyPI/PyPI publication subject to current security and release gates.
|
|
198
|
+
MIT licensing and the maintainer role are owner decisions. The reporting routes
|
|
199
|
+
must be enabled and their availability verified for each release. Registry
|
|
200
|
+
ownership, final artifact checks and publication remain separate observable
|
|
201
|
+
steps. Do not claim that authorization fixes a vulnerability or completes a
|
|
202
|
+
security assessment. Scientific acceptance and human adoption are independent
|
|
203
|
+
of interface stability and registry publication.
|
|
204
|
+
|
|
205
|
+
## Admitting a new engine or integration
|
|
206
|
+
|
|
207
|
+
Do not expand the adapter catalog because a feature is popular or a synthetic
|
|
208
|
+
demo passed. Before accepting an implementation commitment, require:
|
|
209
|
+
|
|
210
|
+
- Repeated, documented blockers in independent real uses and why existing
|
|
211
|
+
supported routes cannot meet the need without semantic loss
|
|
212
|
+
- A named willing maintainer with boundaries agreed by component owners; any
|
|
213
|
+
backup or staffed coverage must be explicit rather than assumed
|
|
214
|
+
- A permitted representative corpus with independent expectations, positive,
|
|
215
|
+
negative, unsupported, invalid and incomplete cases, including key/multiplicity,
|
|
216
|
+
NULL/NaN, Decimal and time boundaries relevant to the integration
|
|
217
|
+
- An explicit resource and maintenance budget covering native dependencies,
|
|
218
|
+
CI/platform cells, performance, evidence readers, security and upgrade costs
|
|
219
|
+
- An owner-approved support decision: supported subset, version/platform matrix,
|
|
220
|
+
stability, failure/abstention rules, migration/deprecation and exit criteria
|
|
221
|
+
|
|
222
|
+
Record the decision and its evidence before adding an engine. Preserve genuine
|
|
223
|
+
native execution and explicit registration; do not simulate a new engine by
|
|
224
|
+
converting another engine's already-computed output. Missing demand, ownership,
|
|
225
|
+
corpus, budget or support approval leaves the proposal pending.
|
|
226
|
+
|
|
227
|
+
## Python 3.10 runtime policy
|
|
228
|
+
|
|
229
|
+
The supported compatibility range includes Python 3.10 through 3.13, with the
|
|
230
|
+
measured scope in [compatibility](compatibility.md). Application deployment
|
|
231
|
+
owners remain responsible for the interpreter's lifecycle, dependency risks and
|
|
232
|
+
their upgrade path. Passing package tests does not provide upstream/vendor
|
|
233
|
+
security maintenance, a backup maintainer or a response deadline.
|