Indice
1. Che cosa fa e che cosa non fa
Fa
Prende un autorevole .py o .m, genera un modulo Analysis standard, conserva il sorgente byte-per-byte, espone i normali controlli Analysis e costruisce uno ZIP installabile con Plugin Install.
Non fa
Non traduce il codice, non corregge formule, non riscrive la matematica, non crea una GUI privata, non sostituisce le API pubbliche con accessi a file interni e non trasforma automaticamente un prototipo in un modulo “production grade”.
2. Dove si apre
La superficie ufficiale è Modules → Script Module Builder…. Il tool è un modulo CORE non selezionabile, di tipo tool, gruppo Scripting / Development.
Nota: la panoramica della GUI resta utile per orientarsi, ma per il contenuto del progetto JSON è ora presente anche una vista dedicata ingrandita.
La stessa implementazione è disponibile da command line attraverso tools/gxtxt_module_builder.py.
3. Anatomia della GUI
builder.py nella dev-031. I controlli, le etichette e l'organizzazione corrispondono all'implementazione corrente.
4. Il progetto JSON
Il file di lavoro usa schema_version: 1. È intenzionalmente semplice e versionabile. Il Builder lo può riaprire e ricostruire.
{
"schema_version": 1,
"id": "research.scale_signal",
"name": "Scale signal",
"description": "Scale one canonical Dataset variable.",
"version": "1.0.0",
"group": "Research",
"license": "GPL-3.0-or-later",
"profile": "A",
"language": "Python",
"source": "scale_signal.py",
"sources": [
{
"id": "primary",
"required": true,
"contracts": "timeseries.table"
}
],
"bindings": [
{
"id": "signal",
"label": "Signal variable",
"required": true
}
],
"fields": [
{
"id": "scale",
"type": "number",
"label": "Scale",
"default": "2",
"required": true
}
],
"required_apis": [
"DATASET_VARIABLE_SCHEMA_API_v3@3",
"CANONICAL_DATASET_API_v2@2"
],
"outputs": {
"datasets": ["research.scale_signal.derived"],
"files": []
}
}
4.1 Campi essenziali
| Campo | Funzione | Regola principale |
|---|---|---|
id | ID stabile del modulo | Deve iniziare con una lettera; ammessi lettere, cifre, punto, underscore e trattino. |
version | Versione del modulo | Formato esatto major.minor.patch. |
name, description, group, license | Metadata del descriptor | Obbligatori e a singola riga. |
profile | Profilo di maturità | A oppure B. |
language | Runtime scientifico | Python oppure Octave. |
source | Sorgente autorevole | Deve esistere ed avere estensione coerente: .py o .m. |
5. New from script e New from registered
5.1 New from script…
Scegli direttamente un .py o .m. Il Builder:
- crea un template con ID
research.<nome_file>; - imposta versione
1.0.0, gruppoResearch, licenza GPL-3.0-or-later e Profile A; - rileva il linguaggio dall'estensione;
- esegue la discovery statica della dichiarazione
GX-TXT-ANALYSIS-SOURCES-V1, se presente.
5.2 New from registered…
Questa strada parte da un script.ini già registrato nella Script Library o nella Sessione. Il Builder legge metadata, language e required_apis, trova source.py oppure source.m accanto al registry e ne calcola il SHA-256.
6. Module details
Il cambio di lingua non converte il sorgente: la sorgente deve già avere l'estensione corretta. Un progetto Python deve puntare a un .py; un progetto Octave a un .m.
7. Analysis Sources
Le Analysis Sources sono i Dataset logici richiesti dal modulo. Devono includere primary, che deve essere required.
| Proprietà | Significato |
|---|---|
id | Nome logico della sorgente, per esempio primary, reference, calibration. |
required | Se il Dataset deve essere selezionato prima del Run. |
contracts | Contratti Dataset ammessi, separabili con ;. |
label | Etichetta leggibile mostrata all'utente. |
purpose | Descrizione dello scopo della sorgente. |
dataset_id | Dataset canonico preferito/default, se registrato e compatibile. |
Il modulo generato usa il normale Analysis Source Map; non viene creato un meccanismo alternativo.
8. Dichiarare le Analysis Sources direttamente nello script
Python e Octave possono dichiarare le sorgenti con una singola riga JSON UTF-8. La discovery legge il testo: non importa e non esegue lo script.
Python
# GX-TXT-ANALYSIS-SOURCES-V1: {"api_version":1,"sources":[{"id":"primary","label":"Measured series","required":true,"contracts":["timeseries.table"],"purpose":"Data to analyze"},{"id":"reference","label":"Reference spectrum","required":false,"contracts":["spectrum.table"],"purpose":"Optional comparison"}]}
GNU Octave
% GX-TXT-ANALYSIS-SOURCES-V1: {"api_version":1,"sources":[{"id":"primary","label":"Measured series","required":true,"contracts":["timeseries.table"],"purpose":"Data to analyze"},{"id":"reference","label":"Reference spectrum","required":false,"contracts":["spectrum.table"],"purpose":"Optional comparison"}]}
Regole principali: massimo una dichiarazione; primary presente e required; ogni sorgente ha id, label, booleano JSON required e array non vuoto contracts. purpose e preferred_dataset sono opzionali.
9. Quando script e progetto dichiarano sorgenti diverse
Le due scelte sono:
Use script declaration
Le sorgenti del progetto vengono sostituite con quelle dichiarate dal sorgente autorevole.
Keep manual source settings
Mantieni le impostazioni manuali. Il Builder registra la scelta insieme al fingerprint SHA-256 della dichiarazione esaminata.
Se in seguito cambia la dichiarazione nello script, il fingerprint non coincide più e il conflitto deve essere riesaminato. Questo impedisce che una vecchia decisione manuale resti valida silenziosamente dopo una modifica del contratto.
10. Variable bindings
Add variable… crea un normale variable selector del framework. I campi sono ID, Visible label, Required e Semantic role opzionale.
A runtime la selezione appare in ctx.parameters come valore qualificato dalla sorgente, per esempio primary.measured_V. Lo script deve risolvere il Variable ID stabile attraverso l'API pubblica dello schema Dataset prima di leggere i dati canonici.
11. Configuration fields
Tipi supportati dal Builder 1.0.2:
| Tipo | Uso tipico |
|---|---|
dataset | Selettore Dataset. |
selection | Selezione persistente del framework. |
temporal_set | Set/intervalli temporali. |
number, integer | Parametri numerici. |
string, text | Testo breve/lungo. |
boolean | Flag. |
choice | Scelta da lista; richiede values. |
file, path | Risorse/file selezionati dall'utente. |
unit | Selettore unità. |
model | Riferimento a un modello registrato. |
table | Tabella ripetibile nativa del framework. |
12. Repeatable table
Il Builder 1.0.1+ genera colonne native del normale editor tabellare. Il dialog consente di iniziare rapidamente, ma per assegnare tipo, source e altri dettagli alle singole colonne conviene modificare il JSON.
{
"id": "samples",
"type": "table",
"label": "Samples",
"min_rows": 1,
"columns": [
{
"id": "variable",
"type": "variable",
"source": "primary",
"required": true
},
{
"id": "weight",
"type": "number",
"default": "1"
},
{
"id": "mode",
"type": "choice",
"values": "include;exclude"
}
]
}
Tipi di colonna ammessi: variable, model, choice, integer, number, string, text, unit.
In Python le righe arrivano in ctx["parameters"]["samples"] come lista di dizionari. In Octave la stessa struttura arriva in ctx.parameters.samples tramite il Bridge. I numeri nelle celle sono stringhe e vanno convertiti dal codice scientifico quando necessario.
13. Required APIs
Require API… aggiunge una dichiarazione di preflight. Ogni API pubblica effettivamente usata dallo script dovrebbe essere dichiarata.
Forma generale:
API_ID@major:provider+capability|capability
Provider e capability sono opzionali. Esempi:
CANONICAL_DATASET_API_v2@2
DATASET_VARIABLE_SCHEMA_API_v3@3
DATASET_PUBLICATION_API_v2@2
PLOT_DATASET_API_v3@3:plot.dataset+plotspec|render
Il Bridge verifica i requisiti prima del calcolo scientifico. Se un requisito non è disponibile, il Run fallisce con diagnostica invece di proseguire in modo parziale.
14. gxtxt_context(): inputs e parameters
inputs
Contiene le Analysis Sources risolte. Esempio: ctx["inputs"]["primary"]["dataset_id"].
parameters
Contiene config fields e variable bindings risolti. Esempio: ctx["parameters"]["scale"] e ctx["parameters"]["signal"].
14.1 Python
# GX-TXT-ANALYSIS-SOURCES-V1: {"api_version":1,"sources":[{"id":"primary","label":"Measured series","required":true,"contracts":["timeseries.table"],"purpose":"Dataset to transform"}]}
from gxtxt import gxtxt_context, gxtxt_api_require, gxtxt_api_call
gxtxt_api_require([
"DATASET_VARIABLE_SCHEMA_API_v3@3",
"CANONICAL_DATASET_API_v2@2",
"DATASET_PUBLICATION_API_v2@2",
])
ctx = gxtxt_context()
dataset_id = ctx["inputs"]["primary"]["dataset_id"]
signal_name = ctx["parameters"]["signal"].split(".", 1)[-1]
scale = float(ctx["parameters"]["scale"])
variables = gxtxt_api_call(
"DATASET_VARIABLE_SCHEMA_API_v3", "list", [dataset_id]
)
signal_id = next(
item["variable_id"] for item in variables
if item["canonical"] == signal_name
)
block = gxtxt_api_call(
"CANONICAL_DATASET_API_v2",
"read_range",
[dataset_id, [signal_id], 0, 0],
)
values = block[signal_id]["values"]
scaled = [float(value) * scale for value in values]
# Publish with the public Dataset Publication API.
# The exact publication payload depends on the Dataset contract you choose.
print(f"Prepared {len(scaled)} scaled values.")
14.2 GNU Octave
% GX-TXT-ANALYSIS-SOURCES-V1: {"api_version":1,"sources":[{"id":"primary","label":"Measured series","required":true,"contracts":["timeseries.table"],"purpose":"Dataset to transform"}]}
gxtxt_api_require({
'DATASET_VARIABLE_SCHEMA_API_v3@3',
'CANONICAL_DATASET_API_v2@2'
});
ctx = gxtxt_context();
dataset_id = ctx.inputs.primary.dataset_id;
parts = strsplit(ctx.parameters.signal, '.');
signal_name = parts{end};
scale = str2double(ctx.parameters.scale);
variables = gxtxt_api_call(
'DATASET_VARIABLE_SCHEMA_API_v3',
'list',
{dataset_id}
);
signal_id = '';
for k = 1:numel(variables)
if (strcmp(variables{k}.canonical, signal_name))
signal_id = variables{k}.variable_id;
break;
endif
endfor
block = gxtxt_api_call(
'CANONICAL_DATASET_API_v2',
'read_range',
{dataset_id, {signal_id}, 0, 0}
);
values = block.(signal_id).values;
scaled = values .* scale;
printf('Prepared %d scaled values.\n', numel(scaled));
15. Output e pubblicazione
La dichiarazione outputs serve a descrivere ciò che il modulo dovrebbe produrre. La pubblicazione effettiva deve avvenire tramite le API pubbliche appropriate.
- I Dataset scientifici vanno pubblicati tramite le Dataset Publication API.
- I file prodotti durante il Run appartengono a
ctx["output_dir"]/ctx.output_dir. - Per rendere persistente un file prodotto usa
DATASET_FILE_PUBLICATION_API_v1.
16. Bundle e risorse
Il bundle serve per helper, tabelle di lookup e risorse statiche che devono viaggiare insieme allo script.
"bundle": [
{"source": "helper.py", "target": "helper.py"},
{"source": "reference/coefficients.csv",
"target": "reference/coefficients.csv"}
]
Il Builder copia ogni file byte-per-byte e crea un inventario SHA-256. Gli helper di codice devono usare lo stesso linguaggio del main script. I target devono essere relativi e sicuri: niente path assoluti, .. o collisioni case-insensitive.
Python
Gli helper sono importabili dal bundle directory per la durata del Run. Le risorse statiche sono raggiungibili da ctx["bundle_dir"].
Octave
Il bundle directory viene aggiunto temporaneamente al path Octave del Run; la risorsa è in ctx.bundle_dir.
Il bundle non viene aggiunto a un path globale e non crea dipendenze permanenti dall'ambiente originale.
17. Profile A e Profile B
| Profilo | Scopo | Requisiti |
|---|---|---|
| A | Packaging di un research workflow. | Può usare normali librerie scientifiche Python/Octave e mantenere l'impostazione di ricerca originaria. |
| B | Target esplicito di produzione. | Richiede almeno scientific_method; è pensato per metodo dichiarato, input/output chiari, test più forti e uso appropriato dei servizi pubblici. |
18. API pubblica opzionale
Questa è una funzione avanzata disponibile nel JSON. Se aggiungi public_api, il Builder genera registrazione Tcl, documentazione API e, per le operazioni opt-in, un provider-owned Script Bridge binding.
"public_api": {
"id": "RESEARCH_SCALE_SIGNAL_API_v1",
"version": 1,
"name": "Scale Signal API",
"capabilities": ["structured_analysis_run"],
"operations": [
{
"id": "run",
"summary": "Run the scale analysis.",
"result_contract": "execution receipt struct",
"read_only": false,
"script_bridge": true,
"arguments": [
{
"name": "dataset_id",
"kind": "Dataset ID",
"required": true,
"target": "source.primary"
},
{
"name": "scale",
"kind": "number",
"required": true,
"target": "config.scale"
}
]
}
]
}
Regole importanti:
- l'ID deve essere nel formato
NAME_vNeversiondeve corrispondere aN; - serve almeno un'operazione;
- le operazioni script-backed sono considerate mutating:
read_only:trueviene rifiutato; - gli argomenti required devono precedere quelli opzionali;
- i target possono essere solo
source.*,binding.*oconfig.*già dichiarati; - il caller non fornisce raw Tcl, callback GUI o path privati.
19. Validate
Validate salva il progetto e controlla che la descrizione sia coerente prima di costruire lo ZIP. Fra i controlli implementati:
Identity
ID valido, versione semantica a tre componenti, metadata obbligatori, Profile e Language validi.
Source
File esistente, estensione coerente con il linguaggio, niente symlink del main source.
Analysis Sources
ID univoci, primary presente e required, contratti validi e conflitto declaration/manual risolto.
Fields e bindings
ID univoci, tipi supportati, choice con values, table con colonne valide e min/max rows coerenti.
APIs
Formato delle requirement e struttura della public API opzionale.
Profile B
Presenza della documentazione scientific_method.
In caso di successo la status line mostra linguaggio e SHA-256 del sorgente autorevole.
20. Build ZIP
Build ZIP ripete la validazione e crea il package nella directory scelta. Il nome è:
<module-id>_<version>.zip
Accanto allo ZIP viene scritto un file .zip.sha256. Se lo ZIP o il relativo checksum esistono già, il Builder rifiuta la sovrascrittura.
Il package è costruito in ordine deterministico, con timestamp ZIP stabilizzato, e contiene checksum sia dei file del bundle sia del payload complessivo.
21. Contenuto del pacchetto generato
Il builder-project.json interno è reso portabile: i percorsi del source e dei bundle puntano alle copie presenti nel package e viene aggiunto source_sha256.
22. Installazione e Run
Il modulo generato usa runner=script_module. La GUI Analysis viene prodotta dai descriptor standard, non da Tcl/Tk personalizzato.
Ogni esecuzione registra in provenance almeno snapshot del sorgente, stato, module version, language, required APIs e SHA-256 del source.
23. Tutorial completo: creare un modulo Python
scale_signal.py. Inserisci, se utile, la riga GX-TXT-ANALYSIS-SOURCES-V1.signal.scale di tipo number, default 2.scale ed esegui.24. Tutorial completo: creare un modulo GNU Octave
Il flusso GUI è identico. Cambiano il main source e il codice scientifico:
- file autorevole
.m; - Language=Octave;
- dichiarazione sorgenti introdotta da
%; - context access con
ctx.inputs,ctx.parameters,ctx.bundle_dir; - le API pubbliche passano comunque da
gxtxt_api_call.
Gli helper .m del bundle vengono aggiunti solo al path temporaneo dell'esecuzione.
25. Uso da riga di comando
GUI e CLI usano la stessa implementazione.
python3 tools/gxtxt_module_builder.py validate research_module.json
python3 tools/gxtxt_module_builder.py build research_module.json /new/package/output
La CLI è particolarmente utile per rebuild ripetibili, CI locale e controllo rapido dei progetti JSON senza aprire la GUI.
26. Errori comuni
| Messaggio / sintomo | Causa tipica | Correzione |
|---|---|---|
module ID must start with a letter... | ID non valido | Usa lettere/cifre/punto/underscore/trattino e inizia con una lettera. |
version must be major.minor.patch | Versione incompleta | Usa ad esempio 1.0.0. |
authoritative source must be an existing .py/.m file | Path o language errato | Correggi source oppure Language. |
sources must include primary | Manca source principale | Aggiungi primary required. |
Builder sources conflict... | Script declaration diversa dal JSON | Usa i pulsanti di review e scegli esplicitamente script o manual. |
choice field ... needs values | Choice senza lista | Imposta valori separati da ;. |
table field ... needs a nonempty columns list | Table senza colonne | Aggiungi almeno una colonna. |
Profile B requires scientific_method | Profile B incompleto | Documenta il metodo scientifico nel JSON. |
refusing to overwrite ...zip | Versione già costruita | Incrementa versione o usa una nuova directory di output. |
| Run fallisce prima del calcolo | Required API non disponibile | Controlla ID/versione/provider/capability dichiarati. |
27. Checklist finale
- Il main source è la copia scientificamente autorevole e non è un symlink.
- Module ID e versione sono stabili e corretti.
primaryè presente e required.- Ogni Dataset necessario è una Analysis Source, non un path privato.
- Ogni variabile scelta dall'utente è un binding standard.
- I parametri modificabili sono fields standard.
- Le table hanno colonne tipizzate coerenti nel JSON.
- Tutte le API pubbliche usate sono dichiarate in
required_apis. - I file ausiliari necessari sono nel bundle.
- Gli output sono dichiarati e vengono pubblicati tramite API appropriate.
- Un eventuale conflitto Analysis Sources è stato risolto esplicitamente.
- Profile B contiene
scientific_method. - Validate passa prima del Build.
- La versione viene incrementata quando cambia source o contratto.
- Dopo l'installazione viene eseguito almeno un Run reale in una Sessione di prova.
28. Provenienza tecnica della guida
La guida è stata preparata sulla copia GX-TXT 0.9.8.10-dev-031 e sul modulo tool.script_module_builder 1.0.2, verificando module.ini, MANUAL.md, README.md, CHANGELOG.md, la guida framework docs/help/script_module_builder.md, la dichiarazione SCRIPT_ANALYSIS_SOURCES_API_v1 e l'implementazione runtime/builder.py.
Le immagini della GUI sono ricostruzioni eseguite direttamente sulla struttura e sulle etichette definite dall'implementazione dev-031. Nel sito statico sono distribuite come asset immagine separati.