Skip to content

Commit 175ef61

Browse files
authored
Merge pull request #55 from ondata/fix/bill-progress-branch-c-camera
fix(bill-progress): --number --branch C restituisce la timeline Camera (#41)
2 parents 80378ac + e88a4b5 commit 175ef61

6 files changed

Lines changed: 48 additions & 9 deletions

File tree

LOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 2026-07-11
44

5+
- **fix `bill-progress``--number --branch C` dà la timeline Camera** (#41, branch `fix/bill-progress-branch-c-camera`). Prima `--number 2617 --branch C --legislature 18` restituiva il record Senato di rimando (`osr:ramo="C"`: una riga, `phase C.2617`, senza date), inutile per chi voleva l'iter Camera. Ora `--branch C` risolve l'atto Camera `ac<leg>_<num>` e ne restituisce la **timeline completa degli stati** (via `cameraIterTimeline`, stesso path di `--uri`): per il dl Covid 2020, 8 stati datati (assegnato→…→legge). `--branch S` invariato (repertorio Senato, stato corrente). **Cambio di comportamento** del valore `--branch C` (prima quasi inutile, nessun uso documentato/testato). Framing onesto dell'asimmetria in description/help/skill/wiki (`iter-statoIter.md`): Camera = timeline stati, Senato = stato corrente (timeline nel feed RSS) — riflette la fonte, non un buco della legislatura. +1 test.
56
- **feat `speeches` — filtro `--date-from`/`--date-to` + colonna `date`** (#37, branch `feat/speeches-date-filter`). Prima gli interventi non erano filtrabili né datati nell'output. **Camera**: la data reale non è sull'intervento (`ods:modified` è il timestamp del record) ma sulla `ocd:discussione` che lo raggruppa (`dc:date` plain `AAAAMMGG`); verificato che copre sia Aula (stenografico, `sezione=assemblea`) sia commissione (bollettino), cardinalità 1 per intervento. Il join+`FILTER` sulle date va dentro la subquery-first (il filtro precede il `LIMIT`); performante solo col range filter sul soggetto → il filtro data richiede `legislature` (0.5s con, degrada senza). **Senato**: `osr:dataSeduta` (xsd:date ISO) già disponibile, filtro con `STR(?ds)` (regge sia xsd:date sia xsd:string). Colonna `date` (YYYY-MM-DD) ora su entrambe le camere — rinominata da `session_date` per parità (nessun consumer esterno). CLI (`--date-from/--date-to`), MCP, skill (tools.md + commands.md) e wiki (`camera/interventi-data.md` nuova) allineati. +2 test (Camera e Senato), 139/139 verdi, tsc pulito.
67
- **workflow PR quasi-autonomo configurato**: aggiunto workflow `CI` su `pull_request`/`push main` (`npm ci`, `npm run build`, `NODE_OPTIONS="--max-old-space-size=4096" npx tsc --noEmit`, `npm test -- --run`) per gate automatico su PR; lato repository abilitato `allow_auto_merge`, aggiornato ruleset `Copilot review for default branch` con `review_on_push=true`, e impostata branch protection classica su `main` con status check richiesto `ci` (strict). Obiettivo: ridurre il ciclo manuale commenta/correggi/committa nelle PR.
78

docs/lod-wiki/camera/iter-statoIter.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ Verificato che il dato a monte contiene la timeline multi-fase **anche per la le
3434

3535
Lo stesso tool `bill-progress` ha due rami con granularità diversa **per costruzione**, indipendente dalla legislatura:
3636

37-
* **Camera** (`--uri <atto>`): timeline completa via `ocd:rif_statoIter` (una riga per stato).
38-
* **Senato** (default): l'entità `osr:Ddl` in SPARQL espone solo lo **stato corrente** (`osr:statoDdl` + `osr:dataStatoDdl`, `osr:fase`/`osr:numeroFase`), **una sola riga**, non una cronologia. La timeline dettagliata delle fasi del DDL Senato (con sedute ed esiti) vive nel **feed RSS** del DDL, non nello SPARQL — il tool la espone come `rss_url`. Vedi [Feed RSS dei DDL Senato](../senato/index.md).
37+
* **Camera**: timeline completa via `ocd:rif_statoIter` (una riga per stato), raggiungibile in due modi — con `--uri <atto>` o con `--number <n> --branch C` (che risolve `ac<leg>_<n>`).
38+
* **Senato** (`--branch S`, default): l'entità `osr:Ddl` in SPARQL espone solo lo **stato corrente** (`osr:statoDdl` + `osr:dataStatoDdl`, `osr:fase`/`osr:numeroFase`), **una sola riga**, non una cronologia. La timeline dettagliata delle fasi del DDL Senato (con sedute ed esiti) vive nel **feed RSS** del DDL, non nello SPARQL — il tool la espone come `rss_url`. Vedi [Feed RSS dei DDL Senato](../senato/index.md).
39+
40+
Attenzione al `--branch` con `--number`: `--branch C` dà la **timeline** dell'atto Camera (molte righe), `--branch S` dà lo **stato corrente** del DDL Senato (una riga). Prima `--branch C` restituiva il record Senato di rimando (`osr:ramo="C"`, una riga senza date), fuorviante per chi si aspettava l'iter Camera (issue #41).
3941

4042
Conseguenza pratica: un DDL Senato che "sembra meno dettagliato" di un atto Camera non è un buco della legislatura, ma questa differenza di modellazione tra i due grafi. Confrontare timeline con timeline (RSS lato Senato) o stato-corrente con stato-corrente.
4143

skills/italian-parliament-cli/references/commands.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,16 @@ italianparliament attendance show --uri http://dati.camera.it/ocd/deputato.rdf/d
132132
## Attività legislativa — Senato
133133

134134
### `bill-progress list`
135-
Iter di un disegno di legge. **Senato** (senza `--uri`): lista DDL con stato corrente, filtrabile per legislatura, `--keyword`, `--number <n>` (+ `--branch S|C`, default `S`) per cercare un atto dal suo numero (es. `--number 1809` → S.1809), `--date-from`/`--date-to`, o per singolo DDL con `--ddl-uri`. **Camera** (con `--uri <atto Camera>`): timeline completa di tutti gli stati attraversati, in ordine cronologico. Stesse colonne in entrambi i casi.
135+
Iter di un disegno di legge. **Senato** (`--branch S`, default): lista DDL con **stato corrente**, filtrabile per legislatura, `--keyword`, `--number <n>` (es. `--number 1809` → S.1809), `--date-from`/`--date-to`, o per singolo DDL con `--ddl-uri`. **Camera**: **timeline completa** di tutti gli stati attraversati, in ordine cronologico, in due modi — con `--uri <atto Camera>`, oppure con `--number <n> --branch C` (risolve l'atto Camera `ac<leg>_<n>`). Stesse colonne in entrambi i casi.
136136
```bash
137137
italianparliament bill-progress list --legislature 19
138138
italianparliament bill-progress list --number 1809 --branch S --legislature 19
139+
italianparliament bill-progress list --number 2617 --branch C --legislature 18 # timeline Camera dl Covid 2020
139140
italianparliament bill-progress list --ddl-uri http://dati.senato.it/ddl/25597
140141
italianparliament bill-progress list --uri http://dati.camera.it/ocd/attocamera.rdf/ac19_2822
141142
```
142143

143-
> Nota: lo stesso numero può esistere in entrambi i rami (`C.1809` e `S.1809`), perciò `--branch` è obbligatorio per disambiguare (default `S`).
144+
> Nota: lo stesso numero può esistere in entrambi i rami (`C.1809` e `S.1809`), perciò `--branch` disambigua (default `S`). Attenzione all'asimmetria: `--branch S` restituisce **una riga** (stato corrente del DDL al Senato), `--branch C` restituisce **la timeline** (una riga per stato, con date) — riflette ciò che le due fonti pubblicano (la Camera lo storico degli stati, il Senato solo lo stato corrente; la timeline Senato vive nel feed RSS).
144145
145146
### `bill-signatories show`
146147
Firmatari di un DDL, **Camera o Senato** (riconosciuto dall'URI): primo firmatario e cofirmatari con nome e link al profilo.

skills/italian-parliament-mcp/references/tools.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ Iter di un disegno di legge, Camera o Senato (stesse colonne in entrambi i casi)
105105
- `ddlUri`: singolo DDL Senato
106106
- `keyword`: cerca nel titolo del DDL
107107
- `number`: numero dell'atto (es. `1809` → S.1809), da abbinare a `branch`. Se ometti `legislature`, usa la legislatura corrente (risolta dinamicamente). Lo stesso numero può esistere in entrambi i rami (C.1809 e S.1809).
108-
- `branch`: ramo per `number`, `S` (Senato, default) o `C` (Camera)
108+
- `branch`: ramo per `number`. `S` (default): repertorio Senato, **stato corrente** del DDL (una riga). `C`: risolve l'atto Camera `ac<leg>_<n>` e ne restituisce la **timeline completa** degli stati (una riga per stato, con date). L'asimmetria riflette la fonte: la Camera pubblica lo storico degli stati, il Senato solo lo stato corrente (la sua timeline vive nel feed RSS).
109109
- `dateFrom`/`dateTo`: intervallo data presentazione
110-
- **Camera** (`uri` = atto Camera `attocamera.rdf/...`): timeline completa di tutti gli stati attraversati, in ordine cronologico.
110+
- **Camera** — timeline completa di tutti gli stati attraversati, in ordine cronologico: con `uri` = atto Camera `attocamera.rdf/...`, oppure con `number` + `branch: C`.
111111

112112
### `bill-signatories`
113113
Firmatari di un DDL, **Camera o Senato** (il ramo è riconosciuto dall'URI): primo firmatario e cofirmatari con nome e link al profilo. Per gli atti di iniziativa governativa, il ruolo è "Governo (proponente)".

src/tools/bill-progress.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ const inputSchema = z.object({
2929
.regex(/^\d+$/)
3030
.optional()
3131
.describe(
32-
"Numero dell'atto Senato (es. 1809 per S.1809). Da abbinare a --branch per il ramo. Include automaticamente le letture successive della navetta con suffisso (es. --number 1353 torna S.1353 E S.1353-B). Se ometti --legislature, con --number la CLI usa di default la legislatura corrente (risolta dinamicamente dall'endpoint Camera) per evitare omonimi storici. Lo stesso numero può esistere in entrambi i rami (C.1809 e S.1809).",
32+
"Numero dell'atto (es. 1809). Da abbinare a --branch per il ramo. Con --branch S interroga il repertorio Senato (S.1809); con --branch C risolve l'atto Camera C.1809 e ne restituisce la timeline degli stati. Per il ramo S include automaticamente le letture successive della navetta con suffisso (es. --number 1353 torna S.1353 E S.1353-B). Se ometti --legislature, con --number si usa di default la legislatura corrente (risolta dinamicamente dall'endpoint Camera) per evitare omonimi storici. Lo stesso numero può esistere in entrambi i rami (C.1809 e S.1809).",
3333
),
3434
branch: z
3535
.enum(["S", "C"])
3636
.optional()
37-
.describe("Ramo per --number: S (Senato, default) o C (Camera)."),
37+
.describe(
38+
"Ramo per --number. S (default): repertorio Senato, restituisce lo STATO CORRENTE del DDL (una riga). C: atto Camera, restituisce la TIMELINE COMPLETA degli stati attraversati (una riga per stato, con date). L'asimmetria riflette la fonte: la Camera pubblica lo storico degli stati, il Senato solo lo stato corrente (la sua timeline vive nel feed RSS).",
39+
),
3840
dateFrom: z
3941
.string()
4042
.regex(/^\d{4}-\d{2}-\d{2}$/)
@@ -73,14 +75,15 @@ const columns = [
7375
export const billProgressTool: Tool<typeof inputSchema> = {
7476
name: "bill-progress",
7577
description:
76-
"Iter legislativo di un disegno di legge. È la SPINA DORSALE per ricostruire l'iter completo di una legge: usalo per le date reali di ogni fase, non generare la timeline a memoria. [SENATO] senza --uri: lista DDL al Senato con stato corrente dell'iter (assegnato, esame in commissione, approvato, ecc.), filtrabile per legislatura, numero atto (--number, es. 1809 per S.1809, con --branch S|C), parola chiave nel titolo e intervallo date. Con --number ma senza --legislature, il default è la legislatura 19 per evitare omonimi storici rumorosi. [CAMERA] con --uri <atto Camera>: cronologia completa (timeline) di tutti gli stati attraversati dall'atto, in ordine cronologico. Stesse colonne in entrambi i casi. Per collegare un atto Camera al suo DDL Senato usa --number (il numero letto dalla timeline Camera) + --branch S: MAI per keyword, per non pescare un atto omonimo diverso.",
78+
"Iter legislativo di un disegno di legge. È la SPINA DORSALE per ricostruire l'iter completo di una legge: usalo per le date reali di ogni fase, non generare la timeline a memoria. [SENATO] senza --uri: lista DDL al Senato con stato corrente dell'iter (assegnato, esame in commissione, approvato, ecc.), filtrabile per legislatura, numero atto (--number 1809 --branch S), parola chiave nel titolo e intervallo date. Con --number ma senza --legislature, il default è la legislatura corrente per evitare omonimi storici rumorosi. [CAMERA] cronologia completa (timeline) di tutti gli stati attraversati dall'atto, in ordine cronologico, in DUE modi: con --uri <atto Camera>, oppure con --number <n> --branch C (risolve l'atto Camera ac<leg>_<n>). Stesse colonne in entrambi i casi. NB: --branch C dà la timeline Camera (una riga per stato), --branch S dà lo stato corrente del DDL al Senato (una riga): l'asimmetria riflette ciò che le due fonti pubblicano. Per collegare un atto Camera al suo DDL Senato usa --number (il numero letto dalla timeline Camera) + --branch S: MAI per keyword, per non pescare un atto omonimo diverso.",
7779
emptyHint:
7880
"Nessun DDL trovato. Se cercavi il DDL Senato di un atto Camera, aggancialo PER NUMERO (--number <n> --branch S), non per keyword. Se usavi --keyword, prova il termine normativo o una radice più corta. Non dedurre l'iter: se non torna, non inventare fasi, date o esiti.",
7981
inputSchema,
8082
examples: [
8183
"italianparliament bill-progress list --legislature 19 --limit 20",
8284
"italianparliament bill-progress list --number 1809 --branch S",
8385
"italianparliament bill-progress list --number 1809 --branch S --legislature 19",
86+
"italianparliament bill-progress list --number 2617 --branch C --legislature 18",
8487
"italianparliament bill-progress list --ddl-uri http://dati.senato.it/ddl/25597",
8588
"italianparliament bill-progress list --legislature 19 --keyword autonomia --limit 20",
8689
"italianparliament bill-progress list --legislature 19 --date-from 2026-04-01 --date-to 2026-04-13",
@@ -100,6 +103,17 @@ export const billProgressTool: Tool<typeof inputSchema> = {
100103
return cameraIterTimeline(cameraUri, columns);
101104
}
102105

106+
// --number con --branch C: l'utente vuole l'iter dell'atto Camera C.<num>,
107+
// non il record di rimando lato Senato (osr:ramo="C" = una sola riga con lo
108+
// stato corrente, senza timeline né date). Risolviamo l'URI dell'atto Camera
109+
// (ac<leg>_<num>) e restituiamo la cronologia completa degli stati, come per
110+
// --uri. Il ramo S resta sul repertorio Senato (stato corrente).
111+
if (input.number && input.branch === "C") {
112+
const leg = input.legislature ?? (await currentLegislature());
113+
const cUri = `http://dati.camera.it/ocd/attocamera.rdf/ac${leg}_${input.number}`;
114+
return cameraIterTimeline(cUri, columns);
115+
}
116+
103117
// Se un URI Senato è passato via --uri, trattalo come ddlUri.
104118
const senatoDdlUri =
105119
input.ddlUri ??

src/tools/tools.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,27 @@ describe("Senato tools", () => {
554554
expect(first.phase).toBe("C.302");
555555
}, 30000);
556556

557+
it("bill-progress: --number + --branch C returns the Camera iter timeline (#41)", async () => {
558+
// dl Covid Camera 2020: --number 2617 --branch C --legislature 18 deve dare
559+
// la timeline dell'atto Camera (più stati datati), non il record di rimando
560+
// lato Senato (una riga, phase C.2617, senza date).
561+
const result = await billProgressTool.execute({
562+
number: "2617",
563+
branch: "C",
564+
legislature: 18,
565+
limit: 100,
566+
offset: 0,
567+
});
568+
expect(result.rows.length).toBeGreaterThanOrEqual(2);
569+
expect(result.rows[0].ddl_uri).toBe(
570+
"http://dati.camera.it/ocd/attocamera.rdf/ac18_2617",
571+
);
572+
expect(result.rows[0].phase).toBe("C.2617");
573+
expect(result.rows[0].status_date).toMatch(/^\d{4}-\d{2}-\d{2}$/);
574+
// deve contenere lo stato finale "Legge"
575+
expect(result.rows.some((r) => /Legge/.test(r.status))).toBe(true);
576+
}, 30000);
577+
557578
it("bill-signatories: returns signatories for a Senato DDL", async () => {
558579
const result = await billSignatoriesTool.execute({
559580
billUri: "http://dati.senato.it/ddl/25597",

0 commit comments

Comments
 (0)