Imported from oracle-samples/oracle-aidp-samples (
ai/claude-code-plugins/oracle-ai-data-platform-fusion-autopilot/skills/workbook-authoring/SKILL.md). Install upstream withnpx skills add oracle-samples/oracle-aidp-samples --skill workbook-authoring. Copyright stays with the author.
Workbook Authoring (Regenerated JSON, Runtime-Valid)
Use this skill to generate full workbook JSON that is both schema-shaped and plugin-runtime-valid for shipped template families.
Scope
- Two-mode authoring:
regenerate_workbookis the primary/default path (full deterministic regeneration).modify_existingis additive and limited to supported scoped edits (filter-value edits, add filter-bar filter, title edits).- Multi-canvas + multi-viz workbooks are allowed and expected when the use case requires them; do not default to single-canvas/single-viz unless explicitly requested.
- Disk-first output is mandatory.
- Public API/token flows are out of scope.
- Server sample workbook inspection is fallback-only.
- Save-target mode is independent from generation mode: update requests should replace existing workbook by default.
Preflight: OAC MCP connection (fail fast)
- Before anything else, confirm the
oac-mcp-servertools are live — this skill reads the OAC catalog through them (discovery,describe_data, save-validation). Probe once with a cheaporacle_analytics-search_catalogcall (or checkclaude mcp list→oac-mcp-server ✔ Connected).- If dead / unauthenticated: STOP with an actionable message — do not
proceed into catalog resolution (it would fail deep with an opaque error,
or worse, read an empty result as "datasets don't exist"). Tell the user:
from the customer project directory, run:
Then restart/reconnect Claude Code (env -u OAC_URL -u OAC_MCP_USER -u OAC_MCP_PASSWORD -u OAC_ADMIN_USER -u OAC_ADMIN_PASSWORD \ aidp-fusion-autopilot dashboard mcp-setup \ --connector-js <path-to-oac-mcp-connect.js>/mcp→ reconnectoac-mcp-server) so the tools activate, then re-invoke. Theenv -u ...wrapper lets the project.envwin over any global shell OAC profile. If this workbook request is part of the Fusion Autopilot journey, write.aidp/autopilot/resume.mdfirst withskills/aidp-fusion-autopilot/write_resume_checkpoint.py. MCP servers bind at session start; the connection cannot be established mid-session. (Autopilot front-loads this as Step 1b.) - A save-unavailable connection is fine (disk-first fallback below); a fully dead connection is not.
- If dead / unauthenticated: STOP with an actionable message — do not
proceed into catalog resolution (it would fail deep with an opaque error,
or worse, read an empty result as "datasets don't exist"). Tell the user:
from the customer project directory, run:
Required MCP tools and capabilities
- Mandatory:
oracle_analytics_execute_logical_sqloracle_analytics_describe_data- Metadata discovery capability:
- prefer
oracle_analytics-find_matching_datasourceswhen available for initial natural-language datasource matching - then use
oracle_analytics-search_catalogfor authoritative catalog resolution - fallback to
oracle_analytics-discover_dataonly when newer discovery tools are unavailable - Modify-mode source acquisition requires one of:
- content resource read capability for
content://workbook JSON (via resources/read), or - user-provided local workbook JSON file path.
- Save/export capabilities are optional and independent:
- if
oracle_analytics-save_catalog_contentis unavailable, run disk-first generation + validation checks and return deterministic disk-only outcome - if save is available but
oracle_analytics-export_workbookis unavailable, proceed with save +viewUrland skip export - Export is opt-in by user intent; default behavior is save + return
viewUrlwithout export
Required local assets
Resolve <WB_SKILL_ROOT> as the directory containing the active workbook-authoring SKILL.md. Common package paths:
-
.agents/skills/workbook-authoring(Codex full zip layout) -
.claude/skills/workbook-authoring(Claude full zip layout) -
skills/workbook-authoring(local skill/plugin install layout) -
fail fast if none exist
-
<WB_SKILL_ROOT>/<TARGET_VERSION>/templates/template-index.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/templates/*.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/metadata-to-json-mapping.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/filter-profiling-contracts.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/calculation-contracts.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/version-field-catalog.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/runtime-profile-contracts.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/semantic-validation-rules.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/plugin-type-aliases.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/viz-runtime-catalog.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/viz-resolution-profiles.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/presentation-polish-contracts.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/edit-operation-contracts.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/support-window.v1.json -
<WB_SKILL_ROOT>/tools/runtime-validation-check.mjs -
<WB_SKILL_ROOT>/tools/modify-workbook.mjs -
<WB_SKILL_ROOT>/tools/regenerate-workbook.mjs -
<WB_SKILL_ROOT>/tools/validate-requirements-trace.mjs -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-contract.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-adapter-contract.v1.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/validation/schema-registry-profile.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/schemas/workbook-schema-manifest.json -
<WB_SKILL_ROOT>/<TARGET_VERSION>/schemas/*.js -
In multi-version installs, choose
<TARGET_VERSION>from installed folders under<WB_SKILL_ROOT>/(minimum supported26.01).
Required workflow
1) Parse intent
Capture:
- visual type
- business question
- dimensions/measures/time fields
- filters and layout expectations, including expected canvas count, viz distribution per canvas, and canvas names when known
- whether user intent is update existing workbook vs create new workbook
- whether detailed traces were explicitly requested (
trace,debug,diagnostics, ortraceRequested=true)
2) Save target resolution (required)
- Keep generation policy fixed: regenerate complete workbook JSON from requirements.
- Detect save capability first:
- if
oracle_analytics-save_catalog_contentis unavailable, skip remote target resolution and continue with disk-only output. - Resolve save mode from user intent:
replace_existingwhen user asks to change/update an existing workbook (default for update intent).create_newonly when user explicitly asks for a new workbook/copy/variant.- Resolve target workbook by capability:
- use
oracle_analytics-search_catalogwhen available. - else use
oracle_analytics-discover_dataonly for metadata discovery and do not attempt remote save target resolution. - In
replace_existingmode: - require exactly one resolved workbook target (
id). - if unresolved or ambiguous, fail fast with actionable message (do not silently create a new workbook).
- In
create_newmode: - create with
parentId+name. - if same-name workbook already exists and user did not request duplicate/copy behavior, fail fast instead of creating duplicates.
3) Authoring mode router (required)
- Route request to
regenerate_workbookunless intent clearly requests a supported scoped modify operation. modify_existingsupports only:- edit existing filter operator/default/source values.
- add filter-bar filter for an existing criteria column.
- edit workbook/canvas/view titles; if title path is missing, create canonical path and then apply title update.
- Route to
modify_existingonly when one source path is available: - catalog content read for
content://, or - user-provided local workbook JSON file path.
- If neither source path is available, fail with actionable guidance to download workbook JSON to disk and provide file path.
- Unsupported modify intents must fail with actionable
not supported in modify_existing mode. - Keep
regenerate_workbookflow unchanged as primary path. - Execute primary regenerate flow through the bundled driver:
node <WB_SKILL_ROOT>/tools/regenerate-workbook.mjs --request <request.json> [--target-version "<YY.MM>"] [--detected-target-version "<YY.MM>"] [--output <workbook.json>]
File-location convention (where the JSONs live). Author per workbook under a
workbooks/<name>/directory besidebundle.yaml(mirrorsoverlays/<name>/andprofiles/):
workbooks/<name>/request.json— the input spec (analysisRequirements).workbooks/<name>/workbook.json— the generated, disk-first output.workbooks/<name>/<name>.redacted.json— the only variant safe to commit.Default
--request workbooks/<name>/request.jsonand--output workbooks/<name>/workbook.jsonwhen the caller doesn't specify paths. Do not commit the rawworkbook.jsonor any*bound*request — they carry the OAC host / dataset UUID / session tokens; the bundle.gitignoreignoresworkbooks/**/workbook*.json+workbooks/**/*bound*.json(allowing*.redacted.json). Never write to/tmp(lost on reboot) or intotests/live/(that path is for skill evidence, not user work).
- Build request payload to satisfy
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-contract.v1.json. - Build
adapterPayloadto satisfy<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-adapter-contract.v1.json. - For
compose_ootb, include approvedanalysisRequirementsbefore generation: - required gate:
brief -> discovery/profile -> requirements artifact -> explicit approval -> generate. analysisRequirements.approval.statusmust beapproved.- Treat
analysisRequirementsas the single approved story/spec planning artifact. Do not introduce a separate YAML or compact-spec runtime. analysisShapeandadapterPayloadare supporting execution inputs:analysisShapemay be explicit, or it may be bootstrapped fromanalysisRequirements.canvases;adapterPayloadremains the datasource/profile evidence.analysisRequirementsmay include workbook intent (workbook.name/description), datasource aliases, reusable field aliases, reusable calculations, report/canvas filters, canvas layout intent, top-level navigation/data actions, and optional theme/presentation hints.analysisRequirementsmust align withanalysisShapecanvas/view IDs when both are provided.- each compose view must include detailed planning (
purpose,grain,bindings,labels,filters,calculations, andsort, optionalinteractions) or supported shorthand that normalizes to those fields. - supported view shorthand includes simple
type/viewType/visualizationvalues plus fields such asx,y,category,value,metric,rows,columns,location, andfilter. - exact
pluginType, explicit semantic-rolebindings, exact calculations, interactions, and full data action metadata remain valid advanced planning; shorthand must not replace detailed planning when exact runtime shape is known. - unsupported shorthand or conflicting shorthand vs explicit bindings must fail fast; do not silently substitute another visualization.
- each normalized
analysisRequirements.canvases[].views[].filters[]entry must include: filterID,columnID,location,scope,operator,default,planningOutcome.- compose preflight lint behavior is controlled by optional
composeFilterTolerance.mode: - default
strict: missing filter fields fail fast with JSON-pointer diagnostics (for example/analysisRequirements/canvases/0/views/0/filters/0/scope) before generation starts. - optional
tolerant: missingscopeauto-fills toglobal; missingdefaultis derived fromadapterPayload.profiling.filterDecisionTrace.derivedDecisionswhen possible; if derivation is not possible, fail fast with deterministic diagnostics. - regenerate output includes
composeFilterToleranceSummarywith mode and auto-fill telemetry. - minimal valid filter object shape:
{"filterID":"flt_year","columnID":"dim_time_year","location":"filter_bar","scope":"global","operator":"in","default":["2025"],"planningOutcome":"applied"}- Recommend (do not require)
analysisShape.canvases[].nameduring initial generation so canvas titles are created correctly in one pass. - If canvas names are omitted, generation remains valid and titles can still be edited later.
- Set
generationStrategyexplicitly for deterministic routing: - prefer
compose_ootbby default for new workbook generation. - use
passthrough_boundonly when one of these is true: - the user explicitly asks to use an existing workbook and modify/preserve its current structure, or
- the user asks to modify a previously
compose_ootb-generated workbook using that workbook as bound input. - Do not let bound input presence alone (
adapterPayload.binding.boundWorkbookJson|boundWorkbookPath) force passthrough in agent routing; setgenerationStrategy="compose_ootb"unless a passthrough condition above applies. - If
generationStrategy="auto"is used, runtime routing is deterministic and will choosepassthrough_boundwhenever bound input exists; avoidautofor new-generation flows. passthrough_boundrequires bound workbook input and should not be blocked by OOTB topology limits.request.workbook.name/request.workbook.descriptionare save-layer metadata inputs only; do not persist them in workbookcontent.json.- Consume regenerate response
saveMetadatafor save-layer handoff (name/description) when save is attempted. - requirements trace uses severity split:
- blocking mismatches (for example unresolved bindings/filters/calculations/placeholders) fail compose.
- warnings (for example title caption mismatch) are returned in
requirementsTraceSummary.warningsand do not block.
4) Modify-existing mode contract (when routed to modify_existing)
- Source acquisition gate (required):
- prefer catalog JSON read (
content://) when available. - otherwise require user-provided local workbook JSON file path.
- if neither source path is available, fail with actionable guidance (download workbook JSON and provide file path).
- Resolve workbook target via catalog (
id/path/name) for remote replace flows. If ambiguous, fail with candidate list and do not write. - Require explicit confirmation before every modify write.
- Source mode defaults to catalog JSON read (
content://). - Same-session fast-path bypass is allowed only when all are true:
- same-session artifact path exists.
- session artifact workbook id is present.
- session artifact workbook id equals resolved target id.
- On fast-path version/concurrency conflict, fail immediately (no auto-read fallback).
- Apply deterministic mutator via
<WB_SKILL_ROOT>/tools/modify-workbook.mjswith--operationset to a supported operation id from<WB_SKILL_ROOT>/<TARGET_VERSION>/model/edit-operation-contracts.v1.json. - Add-filter operation requires
columnIDalready present incriteria.columns.children; if omitted canvas scope defaults to all canvases. - Title-edit operation may create missing canonical title paths (
viewCaption.caption.text) before applying updates.
5) Metadata discovery
- Choose discovery method by tool capability:
- use
oracle_analytics-find_matching_datasourcesfirst for natural-language datasource shortlist when available. - use
oracle_analytics-search_catalogto resolve and validatedatasetsandsubjectAreasauthoritatively. - otherwise use
oracle_analytics-discover_dataonly as compatibility fallback when newer discovery tools are unavailable. - Build shortlist with
id,type,name,xsaExpr,viewUrl. - Use
oracle_analytics-describe_datain two phases: tablesOnly=true- targeted
tableName/tableNames - normalize field map: dimensions, measures, temporal, datatypes, defaults.
6) Filter profiling (required)
- Run deterministic filter profiling probes from
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/filter-profiling-contracts.v1.jsonusingoracle_analytics_execute_logical_sql. - Profile candidate filter columns by class:
- dimensions: top values + cardinality estimate
- measures: min/max (+ bounded distribution sample where needed)
- temporal: min/max + granularity hint
- Enforce guardrails from the contract (deterministic sort/fetch, row/time limits, bounded retries).
- If an individual profiling probe fails, continue with conservative fallback defaults and record fallback reason in filter decision trace.
7) Plugin resolution (required)
- Resolve requested viz plugin type through
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/viz-resolution-profiles.v1.json. - Determine
runtimeContractFamily,canonicalScaffoldTemplateId, andfinalPluginTypefrom resolution profile. - Use
<WB_SKILL_ROOT>/<TARGET_VERSION>/model/plugin-type-aliases.v1.jsononly as compatibility fallback metadata. - If requested plugin type is unmapped in resolution profiles, stop and report missing resolution contract before generation.
8) Profile handshake (version + runtime dialect)
- Resolve target version from installed
<WB_SKILL_ROOT>/<YY.MM>/bundles. - If
targetVersionis provided, it must match an installed bundle folder. - If exactly one version bundle is installed and
targetVersionis omitted, runtime auto-selects it. - If multiple bundles are installed and
targetVersionis omitted, runtime honorsversion-bundles.jsondefaultTargetVersionwhen present. Without a manifest default, runtime prefers26.07when discovery issearch_catalogand save is available; otherwise runtime prefers26.05when installed, else latest. - If a prior save validation payload contains version-mismatch signatures, pass
detectedTargetVersion(or--detected-target-version) to keep retries sticky to the last accepted target. - Always report selected
targetVersionin user-visible output. - Read support-window + runtime contracts from the selected version bundle for deterministic generation and validation-check behavior.
- Resolve the internal schema target ID from the selected support-window entry for generation.
- Resolve runtime profile/dialect from
runtime-profile-contracts.v1.json. - Resolve runtime family from viz resolution profile (not by template guesswork).
- Use default dialect; allow one fallback dialect only when known runtime errors indicate mismatch.
9) Template-first generation + calculations
- Start from resolution profile
canonicalScaffoldTemplateId; if user requested a different supported template, use that. - Keep template IDs stable; bind metadata into selected template.
- Use
metadata-to-json-mapping.v1.jsonfor deterministic binding. - In
compose_ootb, normalize supportedanalysisRequirementsshorthand first, then consume per-view planning (purpose,grain,bindings,labels,filters,calculations,sort) before semantic fallback inference. - Rebind direct
criteria.columns[].columnFormula.expr.expressionvalues from scaffold defaults to target subject-area expressions usingadapterPayload.describe.columns. - Post-bind, validate that every referenced
columnIDresolves incriteria.columnsand each direct formula uses the selected subject-area token and a described target expression; fail fast if unresolved. - Build workbook structure to match requested analysis shape (single or multi-canvas; single or multi-viz per canvas).
- Preserve requested plugin type by default when a requested plugin lock is provided; do not silently substitute viz types.
- Do not invent ad-hoc JSON shapes.
- Evaluate metric fit:
- If base measures satisfy intent, bind base measures directly.
- If no base measure fits, auto-gap-fill using workbook-local calculations from
calculation-contracts.v1.json. - Supported calc types:
EXPRESSION,TEXT_GROUP,TIME_SERIES. - Calculation columns must be persisted under
criteria.columns.childrenwithuserExpression=true,columnFormula.expr.expression, and deterministic calc IDs. - Typed calculations (
TEXT_GROUP/TIME_SERIES) must persistcriteria.criteriaConfig.settings.columnPropertyMap[columnID]withtype,parentExpression, andoptions. - Nested calc references must use
@calculation("<columnID>")and reference calc columns that exist. - Any derived formula column that is not a direct source-column reference must be marked
userExpression=true(do not emit non-editable derived formulas). - Persist formulas in OAC Logical SQL; translate source-workbook dialects first. Do not emit Tableau
COUNTD(...); use governed measures orCOUNT(DISTINCT ...).POSITION(expr1 IN expr2)is valid OAC syntax. - Filter mode defaults to
filter_bar; usefilter_vizonly when explicitly requested. - For
filter_viz, generated wiring must be runtime-complete: viewConfig.settings["viz:filter"].filterIDMap/parameterIDMapmust exist when relevant.- filter-viz row
logicalEdgeLayersmust match map keys (columnIDfor column controls,namefor parameter controls). - every map value must resolve to a real filter control ID linked to the same filter-viz view (
location=filter_viz,filterViz=<viewName>). - If a filter default uses
listParameterBinding/startParameterBinding/endParameterBinding, declare the matchingparameters.settings[].name; generated shared listbox bindings use multi-value text parameters. - Do not persist placeholder UI states such as
NoneorAllintocriteria.filter; persist only real query defaults. - Data actions use top-level
dataActions[], notdataActions.children; BI Navigation and URL Navigation actions must follow the BI Tech source schema and bind context/anchor columns to criteria columns. - if
generationStrategyApplied=passthrough_bound, do not auto-repair invalid filter wiring; fail fast with deterministic diagnostics. - Use profiling outputs to choose filter operators/default values and de-prioritize high-cardinality filter candidates unless explicitly requested.
- If the user requests number-format behavior (for example currency, decimal places, grouping, abbreviation, or negative style), persist number-format config in plugin
viewConfig.settings. - For chart-family settings, use
viewConfig.settings["viz:chart"]: - use
numberFormatfor a shared/default chart formatter. - use per-field overrides with runtime key conventions (do not use dotted keys like
numberFormat.<fieldLabel>): - for chart/table/pivot/autoviz/combo families, use
bidvtchart_number_format_<token>and optional variants likebidvtchart_number_format_<token>:::<columnID>and.tooltip. - for performance tile families, use
numberFormat<token>and optional variants likenumberFormat<token>:::<columnID>and.tooltip. - Number-format payload must follow workbook number-format schema fields (for example
style,currency,useGrouping,minimumFractionDigits,maximumFractionDigits,useAbbreviation,abbreviationScale,negativeValuesStyle,currencyDisplay). - Number-format enum values must be save-compatible:
abbreviationScaleisoff|on|thousand|million|billion|trillion(onmeans automatic abbreviation), andnegativeValuesStyleisdefault|accounting|red|red_accounting(defaultmeans minus-sign negatives). - Do not persist unsupported aliases such as
abbreviationScale:"auto"ornegativeValuesStyle:"minus"; normalize them toonanddefaultbefore validation/save. - Do not place number-format payloads at workbook root or criteria nodes; keep them under the owning plugin
viewConfig.settingspath. - Presentation polish request block is optional and additive:
presentationPolish.mode:auto | off | strictpresentationPolish.layoutTemplateHints: optionaldefaultArchetype,byCanvasID,byCanvasIndexpresentationPolish.titlePolicy: optionalquestion_oriented | preserve_input- Default polish behavior:
- for
compose_ootb, defaultpresentationPolish.mode=auto(apply neutral_v2 layout/style polish + UX lint warnings) - for non-
compose_ootb, defaultpresentationPolish.mode=autounless explicitly disabled - Polish applies deterministic layout archetype normalization (
executive_dashboard,filter_bar,filter_rail,content_grid,cover) and keeps filter preferencefilter_barunless user explicitly requestsfilter_viz. - In
strictmode, severe UX lint findings must fail generation before save (do not bypass runtime checks). - Return
presentationPolishSummaryin normal output witheffectiveChangeCount,layoutChangeCount,styleChangeCount, andnoOpReasons; includepresentationPolishTraceonly when trace is explicitly requested. - Visualization intelligence request block is optional and advisory-only:
visualizationIntelligence.mode:auto | off(defaultauto)visualizationIntelligence.audienceProfile: optional object (for examplerole,targetLevel) used to tune recommendation wording.- Visualization intelligence must never block generation/save; if scoring fails, return deterministic
dvIntelligenceSummary.status=scoring_unavailableand continue. - Return
dvIntelligenceSummaryin normal output withoverallScore,audienceLevel,dimensionScores,recommendations,evidenceCoverage, andversionProfile; includedvIntelligenceTraceonly when trace is explicitly requested. - Best effort documentation link: if
dvIntelligenceSummary.referencesis present, include the first reference URL when explaining scoring to end users.
10) Deterministic validation gate (required)
- Schema validation check via bundled schemas/schema registry.
- Semantic validation check via runtime contracts.
- Calc-aware semantic checks must pass:
- calc references resolve
- calc dependency graph is acyclic
- typed calc columnPropertyMap payload exists and is valid
- calc columns are ordered deterministically before dependents
regenerate-workbook.mjsruns requirements-trace validation, canonicalization, and strict semantic validation check automatically.- Use manual check commands below only for direct debugging or deterministic patch/retry loops.
- Run requirements-trace validation before runtime validation:
node <WB_SKILL_ROOT>/tools/validate-requirements-trace.mjs --request <trace-request.json>
- Run canonicalization check (in-place) before strict validation:
node <WB_SKILL_ROOT>/tools/runtime-validation-check.mjs --input <workbook.json> [--target-version "<YY.MM>"] [--detected-target-version "<YY.MM>"] [--requested-plugin-type "<pluginType>"] --discovery-method "<search_catalog|discover_data>" --save-available "<true|false>" --export-available "<true|false>" [--export-requested "<true|false>"] [--version-selection-reason "<default_policy|user_requested_newer|required_newer_behavior|capability_heuristic_2607|capability_heuristic_2607_missing_fallback_latest|capability_heuristic_2605|capability_heuristic_2605_missing_fallback_latest|validation_fallback|session_sticky>"] --apply-known-patches --in-place
- Then run strict semantic validation check:
node <WB_SKILL_ROOT>/tools/runtime-validation-check.mjs --input <workbook.json> [--target-version "<YY.MM>"] [--detected-target-version "<YY.MM>"] [--requested-plugin-type "<pluginType>"] --discovery-method "<search_catalog|discover_data>" --save-available "<true|false>" --export-available "<true|false>" [--export-requested "<true|false>"] [--version-selection-reason "<default_policy|user_requested_newer|required_newer_behavior|capability_heuristic_2607|capability_heuristic_2607_missing_fallback_latest|capability_heuristic_2605|capability_heuristic_2605_missing_fallback_latest|validation_fallback|session_sticky>"]
- Canonicalization pass must seed runtime defaults (
parameters._version, color/shape service domain scaffolding) to avoid first-open UI dirty rewrites. - Runtime validation check enforces schema acceptance and strips known-safe internal trace payload keys (
oracle.bi.tech.workbookAuthoringTrace) before save attempts. - Must pass global checks and plugin-family checks before save attempts.
--requested-plugin-typeis optional and should be used only for single-anchor-viz lock scenarios.- For multi-viz workbooks, omit
--requested-plugin-type; the check still validates all plugin views and family/runtime invariants. - For modify mode, run validation check with explicit modify context:
node <WB_SKILL_ROOT>/tools/runtime-validation-check.mjs \
--input <workbook.json> \
--discovery-method "<search_catalog|discover_data>" \
--save-available "<true|false>" \
--export-available "<true|false>" \
[--export-requested "<true|false>"] \
[--version-selection-reason "<default_policy|user_requested_newer|required_newer_behavior|capability_heuristic_2607|capability_heuristic_2607_missing_fallback_latest|capability_heuristic_2605|capability_heuristic_2605_missing_fallback_latest|validation_fallback|session_sticky>"] \
--authoring-mode "modify_existing" \
--requested-operation "<operation_id_from_edit-operation-contracts.v1.json>" \
--source-mode "<catalog_read|session_fast_path>" \
--confirmation-state "confirmed" \
--resolved-workbook-id "<targetId>"
- Execution order is strict: do not parallelize
generate -> check -> save -> optional_export. - Parallelism is allowed only for independent metadata discovery reads.
- Runtime validation check capability inputs are mandatory and capability-driven: always pass
--discovery-method,--save-available, and--export-availablefrom runtime tool detection. - Pass optional
--export-requestedfrom explicit user intent for export; if omitted, validation check defaultsexportRequested=false. - If orchestration has explicit version-target intent, pass optional
--version-selection-reason(default_policy|user_requested_newer|required_newer_behavior|capability_heuristic_2607|capability_heuristic_2607_missing_fallback_latest|capability_heuristic_2605|capability_heuristic_2605_missing_fallback_latest|validation_fallback|session_sticky); otherwise validation check derives deterministic fallback reason. Optionally pass--detected-target-versionwhen continuing from a prior save-validation mismatch. - If any required capability input is missing, runtime validation check must fail fast with deterministic
MISSING_EXECUTION_CAPABILITY_INPUTand no save attempt. - If validation check returns
INPUT_ARTIFACT_NOT_READY, treat it as an orchestration/readiness issue and rerun validation check after generation completes. - If filter-viz tiles show
No Data, diagnose filter-viz map/linkage first: - verify
FILTER_VIZ_HAS_REQUIRED_MAPS,FILTER_VIZ_MAP_KEYS_MATCH_LDM_ROW_BINDINGS,FILTER_VIZ_MAP_VALUES_MATCH_EXISTING_FILTER_CONTROLS, andFILTER_VIZ_FILTERCONTROL_LINKAGE_CONSISTENT. - resolve those invariants before attempting save/export retries.
11) Save loop (disk-first)
- Save JSON locally first and return local path.
- For workbook saves, payload must be wrapped as:
content: { json: <workbook-json-object>, blobs?: [...] }- Do not pass workbook root JSON directly as
content. - Pre-save guard: if
type="workbooks"andcontent.jsonis missing, fail fast locally before MCP call with an actionable message. - Keep workbook payload schema-clean: root
name/descriptionmust not be present incontent.json. Use save-layer metadata (saveMetadata) in save call arguments instead. - Example:
oracle_analytics_save_catalog_content({
type: "workbooks",
parentId: "<folderId>",
name: "FIFA18_2Canvas_Analyses_1_8",
userApproved: true,
content: {
json: workbookJson
}
});
- Optional blobs:
content: {
json: workbookJson,
blobs: [...]
}
- Save mode contract:
replace_existing-> calloracle_analytics_save_catalog_contentwith workbookid(replace mode), notparentId.create_new-> calloracle_analytics_save_catalog_contentwithparentId+name(create mode).- Prefer canonical wrapped payload (
content: { json: <workbook-json-object>, blobs?: [...] }) for all saves. - Server/tool may auto-wrap root workbook objects in some environments, but do not rely on auto-wrap behavior in skill workflow.
- Invalid save payload patterns (reject locally before save call):
- file path references as
content(for example/tmp/workbook.json) jsonPath-style wrappers or path indirection for workbook content- non-JSON string content that cannot parse to a JSON object
- Save transport fallback sequence (deterministic, max one retry):
- Pre-save compaction guard: if the workbook JSON is already large enough that Codex MCP argument truncation/transport limits are likely, minify the same workbook object before the first MCP save call.
- Compaction is whitespace-only unless generation knobs are explicitly being changed for a retry; parse original and minified forms and verify canonical deep equivalence (or matching canonical hash) before save.
- Attempt 1 (canonical):
content: { json: <workbook-json-object>, blobs?: [...] }, using the minified-equivalent object when compaction was applied. - If attempt 1 fails with payload-shape/transport signatures (for example
content string must be valid JSON object,workbook content must include json,Unable to parse the provided json, serialization/size transport errors), run one compaction retry if it was not already applied. - If payload truncation/argument-size limits are suspected after canonical compaction, generate one reduced-size retry candidate with
numberFormatting.policy=noneandpresentationPolish.mode=offwhile keeping the same analysis intent and topology. - Attempt 2 (interop fallback): retry with string form accepted by save tool (
contentas stringified JSON object, orcontent.jsonas stringified JSON when wrapper is required by caller environment). - Do not perform additional transport retries after attempt 2.
- If save tool is available, execute the sequence above and stop on first success.
- On save success, return saved target +
viewUrlimmediately. - If user explicitly requested export and export tool is available, run
oracle_analytics-export_workbookand return preview artifact when ready. - If save tool is unavailable:
- skip MCP save without failing generation,
- return deterministic disk-only outcome and local artifact path.
- If save succeeded but export tool is unavailable, skip export and still return saved target +
viewUrl. - In no-save environments,
modify_existingmay return modified local JSON output but must not attempt server-side replace. - In trace mode only, emit
savePayloadMode(canonical_object|stringified_object) andcompactionApplied(true|false). - On save failure, return concrete payload-shape diagnostics including attempted payload mode, matched signature (if any), failure stage, and blocking constraint.
12) Deterministic remediation (one retry max)
If save/runtime returns known error signatures:
- Map error -> patch action from
runtime-profile-contracts.v1.json. - Apply deterministic patch set only.
- Re-run semantic validation check.
- Retry save once.
Example patch run:
node <WB_SKILL_ROOT>/tools/runtime-validation-check.mjs \
--input <workbook.json> \
--discovery-method "<search_catalog|discover_data>" \
--save-available "<true|false>" \
--export-available "<true|false>" \
[--export-requested "<true|false>"] \
[--version-selection-reason "<default_policy|user_requested_newer|required_newer_behavior|capability_heuristic_2607|capability_heuristic_2607_missing_fallback_latest|capability_heuristic_2605|capability_heuristic_2605_missing_fallback_latest|validation_fallback|session_sticky>"] \
--runtime-error "<save-or-runtime-error-text>" \
--apply-known-patches \
--in-place
If second attempt fails:
- return structured diagnostics
- include contract gap summary
- stop auto-retry
13) Server sample fallback policy
- Do not inspect existing server workbooks by default.
- Allowed only when validation checks pass and one remediation retry still fails runtime/visual acceptance.
- When fallback is used, report the missing/insufficient contract rule.
14) Issue capture and feedback package (opt-in sharing)
When authoring fails, prepare a local feedback package that the user may choose to share.
Failure triggers:
- validation check failure
- save validation failure
- export failure
- saved workbook fails to open/render in UI
- deterministic retry exhausted or unresolved contract gap
Feedback package contract (docs-level, agent-generated):
- package folder name:
feedback-<YYYYMMDD-HHMMSS>-<short_slug> - required files in both modes:
ISSUE_REPORT.mdfeedback_manifest.jsonenvironment_context.json- mode enum:
full | sanitized(defaultfullwhen mode is not specified) feedback_manifest.jsonmust include:mode,targetVersion,authoringMode,failureStage,failureCode,failureMessage,includedFiles,omittedFiles,checksums- deterministic
failureStagevalues:validation_check | save | export | ui_runtime | unknown
Mode behavior:
full: include raw artifacts when available (request payload, generated workbook JSON, validation check outputs, save/export error payloads, trace diagnostics).sanitized: include redacted summaries and field-level masks; do not include raw workbook JSON by default; include omitted-artifact inventory in manifest/report.
Sharing policy:
- always create the package locally first
- never auto-share
- present a concise ready-to-share summary and ask whether the user wants to share
- recommend
sanitizedfor external sharing;fullis acceptable for internal skill maintainers - if user declines sharing, keep package local and continue troubleshooting
Runtime invariants to enforce
table: no column-edge layers; row carries dimension+measure.chart_autoviz:innerPluginType,measuresListview entry, embeddedMeasureView_0, hidden color measure layer, nested property additions.chart_autovizdonut normalization: nested property additions must also includemin.<measure>andmax.<measure>entries.oracle.bi.tech.chart.scatter: do not treat scatter as generic multi-measure autoviz. Scatter uses one embeddedMeasureView_0; top-level and nested measure layers must carryobitech-scatterchart#x/obitech-scatterchart#ytags; nested X/Y layers must include the source-backed min/max/median/colorpropertyAdditions; andMeasureView_1-style nested measure scaffolding is blocked until backed by a runtime fixture.chart_combo_multilayer: explicit combodataLayersInfoin viewConfig + logicalDataModel, validactiveDataLayer, nested layer models per declared layer, and non-empty per-layer measure bindings.pivot: requires row edge, column edge, and measures edge bindings.gantt: requires row/category binding plus logicalitemedge with start/end tags (obitech-gantt#start,obitech-gantt#end).parallel_coordinates: requires row binding plus at least two measure bindings on logicalcoledge.performance_tile: requires logical measures binding and primary measure presence.map: geography/category fields bind throughlogicalEdges.detail; metrics bind through map-specific color/size/layer roles, never execution column because OAC renders that role asUnused. Embedded map scaffolds usedataLayersInfoto mirror map logical edges, keep primary row/column edges unbound, carry detail on nestedMeasureView_0row, and use__EmbeddedVizDummyMeasureLink__only as the embedded runtime measure marker.ui_control: plugin view pluginType must be mapped; do not inject chart/table data-model assumptions.layouts.children[].layoutProps.customProps.textmust be a JSON-encoded object string; split layouts must includeoracle.bi.tech.layout.split.layoutMinSize. Generate this field withJSON.stringify, not manual JSON text.- profile-required
reportConfigservice/settings nodes. - runtime-canonical defaults:
parameters._version, missing filter parameter-binding definitions, color measure domains, and shape domains are pre-seeded so UI interaction does not rewrite workbook JSON immediately. - calculations:
@calculation("<columnID>")references must resolve to userExpression columns- no calc dependency cycles
- typed calc entries require
criteria.criteriaConfig.settings.columnPropertyMap[columnID] - no unsupported source-workbook formula dialect such as Tableau
COUNTD(...) - filter parameter bindings resolve to
parameters.settings[].name - data actions use top-level
dataActions[]and source-schema BI Navigation/URL Navigation payloads criteria.filterplaceholder literals such asNone/Allare warning-level diagnostics
Output contract
Default output mode is concise.
By default, return only:
- local JSON file path (if produced)
- saved workbook identifier/path (or explicit disk-only outcome when save is unavailable)
viewUrlon save success- selected
targetVersion(always report this, including auto-selected single-bundle runs) - selected authoring mode (
regenerate_workbookormodify_existing) - semantic validation check result summary
- evidence/traceability summary:
evidenceLevel,requirementsTraceSummary,filterPlanningSummary,componentGraphSummary,fallbackUsageSummary,dvIntelligenceSummary - generation strategy summary:
generationStrategyRequested,generationStrategyApplied,compositionCoverage - export artifact summary only when export was explicitly requested and completed
Detailed traces are opt-in only. Include trace blocks only when user explicitly asks for trace, debug, diagnostics, or sets traceRequested=true.
When trace is requested, additionally return:
- target execution capability block with
targetVersion,executionMode,reasonForVersionSelection,capabilitySource,saveToolDetected,exportToolDetected,discoveryMethod,saveAvailable,exportAvailable,exportRequested - selected template ID + runtime family + dialect
- strategy trace fields:
generationStrategyRequested,generationStrategyApplied,compositionCoverage,unsupportedTopologyReasons - resolution trace block with
requestedPluginType,resolvedFamily,scaffoldTemplate,finalPluginType,fallbackUsed,reason - filter decision trace block with
selectedFilterMode,queryIntents,probeResults,derivedDecisions,fallbackUsed,fallbackReason - save target trace block with
requestedSaveIntent,resolvedSaveMode,resolvedWorkbookTarget,createBlockedByCollision,reason - when in modify mode, modify trace block with
requestedOperation,resolvedWorkbookTarget,sourceMode,confirmationState,mutationsApplied,pathsChanged,fallbackUsed,fallbackReason - keep filter/modify traces in tool/validation check output only; do not persist internal trace keys in workbook payload JSON
- do not expose internal channel keys or internal
projectVersionIDs in user-facing trace/output - include
dvIntelligenceTraceonly when trace is explicitly requested
On save success, return immediately:
- saved workbook identifier/path
viewUrl
If export was explicitly requested and completed, return:
- export artifact summary
On failure, return:
- error text and available validation details
- applied patch actions (if any)
- contract gap report when unresolved