feat(poiesis-charts): scaffold new crate per B-005 - #4318
Conversation
|
Triage: the failing condition is
That URI is the canonical SVG namespace identifier (matched by string Unrelated: Security / No AI Attribution were queued behind a dead |
04b6bfa to
a8c8eb8
Compare
…l + deterministic SVG emitter New aletheia-internal crate `poiesis-charts` implementing the B-005 acceptance contract foundations: - Parse-don't-validate `Chart` model with closed `ChartKind`, newtyped `FactId`/`FactCite`, and an `Axes` tree whose defaults match the offsite slide-3 chart's nice-rounded extents. - Static render-path decision rule: `ChartKind::render_path()` plus axis-scale routing at `Chart::validate`. Vega-Lite kinds and `log`/ `time` scales hard-fail with `Error::VegaRequired` when the `charts-vega` feature is off. - Hand-rolled SVG combo emitter (`render::kinds::combo`) reproducing the offsite navy/teal dual-axis composition, with the determinism contract enforced in code: `format::format_number` is the only path from `f64` to chart text, `format::coord` is the only path to SVG coordinate attributes, group source order is fixed. - `theme::ResolvedTheme` seam carrying `Themed` (CSS var) and `Resolved` (literal hex) color modes — geometry identical between them so HTML deck and PPTX-bake outputs match byte-for-byte up to fill attribute. - Per-kind design notes for the eight stubbed arms (bar/column/line/area/scatter/pie/doughnut/stat) under `crates/poiesis/charts/docs/design/` ready for implementation fan-out. - 30 unit tests; combo emitter has a re-emit-must-be-byte-identical determinism test. Stubbed: per-kind emitter arms beyond `combo`; tick + gridline rendering inside `combo`; Vega-Lite shell-out wiring. Each is a typed `Error::EmitterStub` and tracked by name in `render.rs` + the design docs. Gate-Passed: kanon 0.1.0
…emitter Extract the W3C SVG 1.1 XML namespace URI into a single `SVG_NAMESPACE` constant and reference it from `emit_svg_open`. The constant carries the spec citation at the declaration site so future emitters can reuse the same source-of-truth instead of repeating the literal. Behavior is unchanged: the emitted combo SVG is byte-identical to before, verified by the existing `output_is_deterministic_across_two_renders` test. Gate-Passed: kanon 0.1.0
Adds a # Examples section to format_number to illustrate the three most common format modes. Also refreshes _llm/L3-api-index/poiesis-charts.md and manifest.toml to reflect the updated doc comment. Gate-Passed: kanon 0.1.0
…sonar.inclusions Gate-Passed: kanon 0.1.0
e475bdd to
74ee7fd
Compare
|
🤖 I have created a release *beep* *boop* --- ## [0.30.0](v0.29.0...v0.30.0) (2026-05-30) ### Features * **aletheia:** faithful import consumer for [#4163](#4163) (PR3/4) ([#4357](#4357)) ([4e49dbe](4e49dbe)) * **aletheia:** populate working_state + typed knowledge in export ([#4163](#4163) PR2/4) ([#4351](#4351)) ([702129e](702129e)) * **diaporeia:** wire memory.* MCP tools to organon executor ([#4117](#4117)) ([#4352](#4352)) ([7f2e243](7f2e243)) * **graphe:** portability raw entry points for [#4163](#4163) (PR1/4) ([#4349](#4349)) ([f267fe5](f267fe5)) * **poiesis-charts:** implement column + bar SVG emitters (B-005) ([#4368](#4368)) ([3559002](3559002)) * **poiesis-charts:** implement line + area SVG emitters (B-005) ([#4372](#4372)) ([2ca94ac](2ca94ac)) * **poiesis-charts:** implement pie + doughnut SVG emitters (B-005) ([#4371](#4371)) ([996dbf3](996dbf3)) * **poiesis-charts:** implement scatter SVG emitter (B-005) ([#4369](#4369)) ([6261c8b](6261c8b)) * **poiesis-charts:** implement stat KPI SVG emitter (B-005) ([#4374](#4374)) ([1416fa0](1416fa0)) * **poiesis-charts:** implement Vega-Lite shell-out emitter (B-005) ([#4373](#4373)) ([e6c9b70](e6c9b70)) * **poiesis-charts:** scaffold new crate per B-005 ([#4318](#4318)) ([fa2e374](fa2e374)) * **poiesis-core:** land B-001 envelope + factbase + open component registry ([#4350](#4350)) ([0cb2bd3](0cb2bd3)) * **poiesis-doc:** pandoc availability probe + flake.nix pin (B-014) ([#4361](#4361)) ([d5efe1d](d5efe1d)) * **poiesis-doc:** scaffold Pandoc backend module, AST serializer, Lua filter stubs (B-012) ([#4365](#4365)) ([23dbe91](23dbe91)) * **poiesis-sheet:** wire B-007 workbook feature flag, error type, and module declarations ([#4353](#4353)) ([f6e574d](f6e574d)) * **poiesis-theme:** B-002 foundation — CSS byte-parity, OOXML clrScheme+fontScheme, doc-vars, extended summus tokens ([#4370](#4370)) ([b0c4319](b0c4319)) * **poiesis-theme:** base PPTX sink (B-002-B) ([#4378](#4378)) ([f072bfe](f072bfe)) * **poiesis-theme:** LaTeX template sink (B-002-C) ([#4380](#4380)) ([8cc683d](8cc683d)) * **poiesis-theme:** reference.docx sink (B-002-D) ([#4381](#4381)) ([520a9b3](520a9b3)) * **poiesis-theme:** Typst template sink (B-002-C) ([#4379](#4379)) ([cf48d61](cf48d61)) * **poiesis:** add chromium CDP printer for HTML-to-PDF conversion ([#4377](#4377)) ([bd4e29e](bd4e29e)) * **poiesis:** add deck-layout solver and deck HTML/CSS renderer ([#4360](#4360)) ([5aa1472](5aa1472)) * **poiesis:** add image-text, timeline, comparison, blank component packs ([#4367](#4367)) ([457efd7](457efd7)) * **poiesis:** add stat, quote, chart, table, image-full component packs ([#4366](#4366)) ([4a3df26](4a3df26)) * **poiesis:** add title, section, bullet, two-col component packs ([#4356](#4356)) ([dde8451](dde8451)) * **poiesis:** retire poiesis-text; migrate callers to poiesis-doc/typst (B-013) ([#4354](#4354)) ([f13df45](f13df45)) ### Documentation * **instance:** refresh stale v0.13.x version references to v0.29.0+ line ([#4347](#4347)) ([01bc922](01bc922)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>




Summary
poiesis-chartscrate per B-005 (poiesis chart subsystem — hand-rolled SVG + Vega-Lite fallback).Chartmodel, the static render-path decision rule, the deterministic SVG combo emitter that reproduces the offsite slide-3 chart geometry, and the theme-binding seam (Themed/Resolvedcolor modes).bar/column/line/area/scatter/pie/doughnut/stat) so the implementation fan-out is unblocked.Crate shape
What's implemented vs. stubbed
comborx=3columns,r=9markers, polyline. Themed mode emitsvar(--tone-*), Resolved emits literal hex.bar,column,line,area,scatter,pie,doughnut,statError::EmitterStub). Per-kind design underdocs/design/<kind>.md.heatmap,boxplot,sankey,candlestick,log/timescalescharts-vegafeature. Hard-fail withError::VegaRequiredwhen disabled.combogridlines + tick text<g class=\"gridlines\">/<g class=\"axes\">placeholders emitted. Tick math is inscale::ticksbut not yet wired into the emitter.instagolden snapshot of the full offsite SVGrender/vega.rsexists as a feature-gated stub.B-005 acceptance — current state
theme: summus; zero color literals in specResolvedTheme::summus_stubmirrors the offsite palette; tests assert navy/teal route via theme.Cite(FactId); verify reconcilesPoint::y: FactCitetypes it in. Verifier integration lands with B-008.instagolden)themed) and PPTX (resolved or baked)ColorMode::Themed/Resolvedboth emit; HTML/PPTX wiring lands with B-003/B-004.ResolvedThemeis the seam; swapping it switches every fill/stroke.charts-vegaoff → hard parse errorChart::validatereturnsError::VegaRequired. Tested.Completion plan for follow-ups
Each stub is tracked in
crates/poiesis/charts/docs/design/<kind>.md. The natural ordering:combogridlines + tick text +instagolden — closes the determinism leg of acceptance feat(ui): WebUI code review fixes — hljs, emoji, mobile, slash commands #4.column+linearms — direct extracts from thecomboprimitives (~70% reuse).bar+area+scatter— small variations on column/line.pie+doughnut+stat— share an arc-path primitive.render/vega.rs— under thecharts-vegafeature.ResolvedTheme::summus_stuband depend onpoiesis-themewhen it lands.Gate
cargo fmt --check— PASScargo check --workspace— PASScargo clippy -p poiesis-charts --all-targets -- -D warnings— PASScargo test -p poiesis-charts— PASS (30 tests)kanon gate --tier full— PASS (Gate-Passed trailer on HEAD)mcp__kanon__standards_name_check word=charts— free (no collisions)Naming
chartspasses GNOMON L1–L4:slides,sheet,text,doc,lint,verify,intake,scaffold,inspect,typst,diff— English domain words rather than Greek roots, deliberately distinct from thealetheia//theatron/Greek-named cognition substrate).bar,column,line,area,combo,scatter,pie,doughnut,stat,heatmap,boxplot,sankey,candlestick) is the canonical chart-vocabulary word — name-checked free, no Greek strain.Test plan
--all-targetsclippy still passes under workspace-wide gatesdocs/design/*.mdbefore kicking off the per-kind fan-outSonarCloud quality gate: spurious SCA finding
The SonarCloud "C Security Rating on New Code" failure on this PR is a single SCA (dependency-analysis) annotation against the new crate's
Cargo.toml:This is a false positive for a cargo-workspace member crate. Cargo workspaces produce one shared
Cargo.lockat the workspace root; member crates do not (and should not) carry their own lockfile — see The Cargo Book §Cargo.toml vs Cargo.lock and the Cargo workspace resolver. The repo's authoritativeCargo.locklives at the workspace root (also touched by this PR for the new member's transitive deps), so every dependency is pinned to an exact version — Sonar's SCA simply does not walk back to the workspace root from a memberCargo.toml.Operator decision: marked spurious. Suggested durable fix (separate, repo-wide PR) is one of:
sonar-project.propertiesat the repo root withsonar.exclusions=crates/**/Cargo.toml(excludes member manifests from SCA only — rootCargo.toml+Cargo.lockstill drive dependency analysis), orOther checks on this PR are green (no AI attribution, gate-attestation with
Gate-Passed: kanon 0.1.0, cargo deny, scan). The included refactor commit centralizes the spec-mandated XML namespace constant — orthogonal quality work, not a Sonar fix.