diff --git a/docs/roadmap/future.md b/docs/roadmap/future.md index 876f9a6..8a38309 100644 --- a/docs/roadmap/future.md +++ b/docs/roadmap/future.md @@ -167,8 +167,10 @@ content selection, core-owned rendering, a text fallback with optional templates and universal format availability. Explicit operator selection wins; otherwise core selects text for a supplied template or chooses from the logical report shape. Command-specific format defaults are omitted from the initial API. -Plain text, YAML, and JSON land together; representation, template, and -native-document details remain there. XML is removed from current consideration. +Plain text, YAML, and JSON land together. The roadmap selects standard Go JSON +serialization conventions for ordinary report values, with separate core +adaptation for native configuration YAML. Text-template and native-document +decisions remain there. XML is removed from current consideration. Markdown and other potential formats are not selected for this adoption; new core formats will work with existing commands without per-command adoption. diff --git a/docs/roadmap/promptkit-v0.19.0.md b/docs/roadmap/promptkit-v0.19.0.md index 7fdb6a5..79772c2 100644 --- a/docs/roadmap/promptkit-v0.19.0.md +++ b/docs/roadmap/promptkit-v0.19.0.md @@ -398,24 +398,47 @@ existing reporting facility rather than creating a second delivery lifecycle. ### Agreed shared representation rules -Centralize representation rules as well as encoders. Define how report fields, -field names, omissions, numbers, and custom serialized values become output so -different renderers do not silently give the same report different meanings. -The objective is to prepare a report once and render that representation in -multiple formats, avoiding a separate translation tree per format. +**Agreed:** use Go's standard `encoding/json` serialization conventions to +interpret ordinary Go report values. Prepare one logical representation for +automatic selection and rendering in text, YAML, and JSON. This selects how Go +values become report data; it does not select JSON as the default output format. -Use Go report values with small, explicit adaptations where needed. Owned -report values follow shared naming and representation conventions; suitable -upstream values can reuse their established serialization contracts through a -shared adapter. Preserve meaningful distinctions among absent, null, false, -zero, and empty values, and avoid numeric precision loss in intermediate -conversions. Paths, durations, and other values needing a different presentation -can use thin projections. Do not assume JSON tags or custom JSON serialization -automatically have the same meaning to a YAML encoder. +Reuse the standard library's field selection, JSON tags, omission rules, nested +value handling, and supported custom JSON serialization. Avoid a new CommandKit +tag convention or reflection-based serialization engine. Suitable upstream +values can reuse their existing JSON contract; thin projections remain useful +when the desired operator content differs from that representation. -Exact conventions, serialization-contract selection, and adapter APIs need to be -specified during design. A large public document model or custom reflection -framework is not selected by this decision. +- **One field interpretation.** JSON field tags and custom serialization govern + ordinary values in every output format. Conflicting YAML tags or YAML-specific + serialization do not change that interpretation. For example, a field tagged + `json:"retry_count" yaml:"retries"` appears as `retry_count` in both JSON and + YAML. Do not independently serialize the original Go value with each encoder. +- **Explicit omission.** Honor omissions selected by the JSON contract. Core + does not additionally hide zero, false, empty, or null values for brevity. + Preserve the remaining distinctions among absent, null, false, zero, and empty + values through conversion and rendering. +- **Preserved numeric values.** Avoid precision loss in intermediate conversion, + including accidental rounding of large integers through floating point. This + preserves the serialized value rather than promising precision beyond the + supplied value and its serialization contract. +- **Observable failures.** Values rejected by the serialization contract produce + presentation errors through the existing reporting lifecycle. Do not silently + drop unsupported data or substitute arbitrary string representations. + +**Agreed separate treatment:** native configuration YAML uses explicit core +adaptation with defined cross-format mappings, not blind conversion through the +ordinary JSON path. Preserve native YAML semantics and disclosure rules when +YAML is requested, and avoid silent loss of richer YAML information. The adapter +API, supported mappings, and multiple-document behavior remain part of the +native-document decision below. This is not an exemption from universal formats +or permission for integration-owned formatting pipelines. + +This approach reduces new machinery by reusing standard serialization and +centralizing the remaining conversion and rendering work. Exact internal +representation and adapter APIs remain implementation design tasks; a large +public document model is not selected. Validate representative reports before +assuming that an upstream type can be handed off without adaptation. ### Agreed plain-text rendering @@ -441,10 +464,6 @@ per-format application renderers are not the selected mechanism. ### Remaining core reporting decisions -- **Shared representation contract.** Specify field/tag and custom-marshaling - precedence, omission and scalar rules, supported Go report values, and how - unsupported values are reported. Keep adapters explicit and avoid silent - numeric loss. This concerns report data, not arbitrary runtime objects. - **Text handoff.** Settle the template API and helper functions, whether templates receive the original Go value or shared representation, fallback conventions, and template preparation and failure behavior. Prefer a small @@ -458,8 +477,10 @@ per-format application renderers are not the selected mechanism. Exact public signatures, flag integration/collision handling, and replacement of existing format plumbing are implementation design tasks. The decisions -above do not reopen content selection, universal formats, automatic selection, -or delivery of all three initial formats together. +above do not reopen content selection, JSON conventions for ordinary report +values, universal formats, automatic selection, or joint format delivery. +Report serialization does not settle the separate JSON input-number conversion +choices in OD-2 and OD-11. ## Initial report implementation approach @@ -476,13 +497,14 @@ Use the capability in core, both integrations, and a maintained application-owne command example. A separately versioned output module or custom serialization engine is not needed. Follow module release/dependency ordering under OD-7. -Prefer directly encoding suitable native inspection/report values or a thin Go -projection with serialization tags. Do not mirror a whole upstream object graph -just to rename fields or rearrange equivalent data. Reuse small path, snapshot, -location, and duration projections where they are genuinely needed. Types whose -intended representation depends on JSON tags or custom JSON serialization cannot -be assumed to encode identically under YAML; reuse their supported serialization -or provide a small explicit adapter rather than inventing a reflection framework. +Prefer handing off suitable native inspection/report values or a thin Go +projection using the agreed JSON serialization conventions. Do not mirror a +whole upstream object graph just to rename fields or rearrange equivalent data. +Reuse small path, snapshot, +location, and duration projections where they are genuinely needed. Core reuses +the JSON contract across renderers; migrate YAML-only report tags or provide a +thin projection where necessary. Native configuration documents follow their +explicit adaptation path rather than the ordinary Go-value path. Exceptions serve concrete report semantics: preserving absent/null/false/zero and empty collections, expressing paths and durations readably, projecting safe @@ -504,8 +526,8 @@ incidental formatting detail in tests. 1. **Confirm remaining implementation choices.** Use the accepted flags, report content, and automatic format policy as the MVP target. Resolve the remaining - core representation, text-template, and native-document decisions; specify - the public API. + text-template and native-document decisions; specify the public API and + internal conversion design under the agreed JSON representation contract. Resolve outstanding acquisition/binding grammar and flag collisions; use concrete examples to review report details during implementation rather than reopening accepted scope. @@ -562,8 +584,8 @@ CommandKit to retest PromptKit rendering, schema, namespace, or ConfigKit resolution algorithms. Default tests remain offline and independent of real credentials. -- [ ] Remaining representation, text-template, and native-document decisions - are recorded. Public signatures and shared representation conventions are +- [ ] Remaining text-template and native-document decisions are recorded. + Public signatures and shared representation conventions are documented with implementation. - [ ] Core owns universal `--format` options, help, validation, and selection. Added core formats work with existing commands without refactoring or local @@ -585,10 +607,15 @@ Default tests remain offline and independent of real credentials. handlers submit report data without their own format switches or encoder setup. Existing quiet-mode, presentation-failure, and domain-outcome behavior is preserved through the Reporter lifecycle. -- [ ] Representative report values preserve field meanings, selected omission - rules, null/false/zero/empty distinctions, and numeric values. Explicit - upstream serialization adapters honor the selected contract rather than - accidentally applying a different encoder's tag or marshaling rules. +- [ ] Ordinary Go reports follow the standard JSON contract across formats, + including JSON tags, supported custom serialization, and selected omissions. + Conflicting YAML tags do not rename fields or change values in YAML output. + Verify that automatic selection follows the resulting logical shape. +- [ ] Representative reports retain null/false/zero/empty distinctions and + numeric values through conversion, including large integers. Unsupported + values and serialization failures remain observable presentation failures. +- [ ] Native YAML follows explicit core adaptation with the selected mappings, + retaining native meaning without silent loss through JSON conversion. - [ ] Core, both integrations, and a maintained application-owned command exercise the public reporting capability. Suitable duplicate selection and encoding code is removed; core has no optional integration dependencies. @@ -744,9 +771,10 @@ These decisions concern significant choices within the proposed scope. Resolved items retain their numbers and record the agreed decision. OD numbers are local to this roadmap, not the retired adoption documents. -The core ownership, text fallback/template, universal-format, automatic-selection, -and joint format-delivery decisions are now agreed above. Their remaining design -details are listed under [remaining core reporting decisions](#remaining-core-reporting-decisions). +The core ownership, JSON representation conventions, text fallback/template, +universal-format, automatic-selection, and joint format-delivery decisions are +now agreed above. Remaining details are listed under +[remaining core reporting decisions](#remaining-core-reporting-decisions). Outstanding integration choices are provider JSON decoding in OD-2, namespace applicability in OD-3, empty comparison collections and binding design in OD-9, and override grammar/acquisition details in OD-11. Exact helper names and report