Skip to content

fix(privacy-guard): render masked columns in canvas_publish_rows datasetId publishes#326

Open
Weegy wants to merge 1 commit into
mainfrom
fix/privacy-guard-masked-canvas
Open

fix(privacy-guard): render masked columns in canvas_publish_rows datasetId publishes#326
Weegy wants to merge 1 commit into
mainfrom
fix/privacy-guard-masked-canvas

Conversation

@Weegy

@Weegy Weegy commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Problem

Result tables on Privacy-Shield turns rendered with empty masked columns and no guard badge (live-verified on Fly: "offene Debitorenrechnungen" → Rechnungsnummer/Kunde blank).

Root cause (proven by repro + Fly logs): the real path is canvas_publish_rows with a server-resolved datasetId — NOT v4_render_answer (which #324 fixed). resolveDatasetForRender returns the real masked values keyed by the dataset's field path. But patchComposition mapped cells as resolvedRow[skeletonColumn.fieldKey], and the agent's skeleton fieldKeys don't all match the real paths (Odoo name/partner_id/invoice_date_due vs agent's invoice_number/customer_name/due_date) → mismatched columns render empty. Columns that happened to use real Odoo field names (invoice_date, amount_total) filled fine.

Fix — generic, at the single data-plane boundary

  • resolveDatasetForRender (harness-plugin-privacy-guard) now returns each column's classification (sensitive-masked | safe-cleartext); type added to PrivacyResolvedDataset in plugin-api.
  • canvas_publish_rows datasetId branch (omadia-ui-orchestrator) derives the table columns from the resolved dataset: fieldKey = authoritative path, privacy:"guard-protected" iff sensitive-masked, humanized-path label fallback. Emitted as data.columns.
  • patchComposition uses those columns when present: maps cells by the real paths (masked values now populate), preserves the agent's human labels by position, replaces the table columns, carries the privacy flag. Odoo many2one [id,"Name"] tuples render the display name (not raw JSON). Agent-authored (non-datasetId) publishes are unchanged.

This fixes empty masked cells + the missing badge for all datasetId-based canvas producers, not just one path.

Pairs with

omadia-ui renderer (feat/privacy-guard-result-display): shield badge in the column header + violet cell highlight on column.privacy. Schema tableColumn.privacy enum merged in #324.

Tests

  • New canvasPublishMaskedColumns.test.ts: masked column shows the real value, carries guard-protected, agent label preserved by position, extra dataset column uses humanized label.
  • 209 relevant regression tests (uiOrchestrator/canvas/privacyV4) green; full build clean (Node 22).

Residual risk (flagged for live verification)

Label reconciliation is by position (dataset column i ↔ skeleton column i). FieldKeys/values are always correct (keyed by path); only the human label mapping is order-sensitive. Correct for the proven Odoo case; one live canvas check on the masked-invoice query recommended (this PR + Fly deploy → local UI re-test).

…setId publishes

The real-world result path. PR #324 fixed v4_render_answer, but query result
tables actually render via canvas_publish_rows with a server-resolved datasetId.
There, cells were mapped as resolvedRow[skeletonColumn.fieldKey]; the agent's
skeleton fieldKeys do not all match the dataset's real field paths (e.g. Odoo
`name`/`partner_id`/`invoice_date_due`), so mismatched columns — including the
masked ones — rendered empty, with no privacy badge.

Generic, path-agnostic fix at the single data-plane boundary:
- resolveDatasetForRender now returns each column's `classification`.
- canvas_publish_rows (datasetId branch) derives the table columns from the
  resolved dataset: fieldKey = authoritative path, privacy = "guard-protected"
  iff sensitive-masked, label = humanized path fallback.
- patchComposition uses those dataset columns when present: maps cells by the
  real paths (so masked values populate), preserves the agent's human labels by
  position, replaces the table's columns, and carries the privacy flag. Odoo
  many2one [id,"Name"] tuples now render the display name, not raw JSON.
  Agent-authored (non-datasetId) publishes are byte-for-byte unchanged.

Fixes empty masked cells + missing guard badge for ALL datasetId canvas
producers. Pairs with omadia-ui renderer (badge/highlight on column.privacy).

Tests: new canvasPublishMaskedColumns + 209 relevant regression tests green
(node 22); full build clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant