- name
- workbook-authoring
- description
- Generate, bind, validate, save, and preview OAC workbook JSON using deterministic templates and OAC MCP. Use when creating or updating supported OAC workbook visualizations over a verified dataset.
# Workbook Authoring (Regenerated JSON, Runtime-Valid)
## Bundled CLI
Resolve `<plugin-root>` as the directory two levels above this `SKILL.md`.
On macOS/Linux, invoke `"<plugin-root>/bin/aidp-fusion-autopilot"`; on Windows,
invoke `"<plugin-root>\\bin\\aidp-fusion-autopilot.cmd"`. Command examples below
use `aidp-fusion-autopilot` as shorthand only—do not assume the plugin's `bin/`
directory is on `PATH`.
Use this skill to generate full workbook JSON that is both schema-shaped and plugin-runtime-valid for shipped template families.
## Scope
1. Two-mode authoring:
2. `regenerate_workbook` is the primary/default path (full deterministic regeneration).
3. `modify_existing` is additive and limited to supported scoped edits (filter-value edits, add filter-bar filter, title edits).
4. 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.
2. Disk-first output is mandatory.
3. Public API/token flows are out of scope.
4. Server sample workbook inspection is fallback-only.
5. Save-target mode is independent from generation mode: update requests should replace existing workbook by default.
## Preflight: OAC MCP connection (fail fast)
0. **Before anything else, confirm the `oac-mcp-server` tools are live** — this
skill reads the OAC catalog through them (discovery, `describe_data`,
save-validation). Probe once with a cheap `oracle_analytics-search_catalog`
call (or check `codex 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:
```bash
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>
```
Then **restart/reconnect Codex** (`/mcp` → reconnect
`oac-mcp-server`) so the tools activate, then re-invoke. The `env -u ...`
wrapper lets the project `.env` win over any global shell OAC profile. If
this workbook request is part of the Fusion Autopilot journey, write
`.aidp/autopilot/resume.md` first with
`skills/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.
## Required MCP tools and capabilities
1. Mandatory:
2. `oracle_analytics_execute_logical_sql`
3. `oracle_analytics_describe_data`
4. Metadata discovery capability:
5. prefer `oracle_analytics-find_matching_datasources` when available for initial natural-language datasource matching
6. then use `oracle_analytics-search_catalog` for authoritative catalog resolution
7. fallback to `oracle_analytics-discover_data` only when newer discovery tools are unavailable
8. Modify-mode source acquisition requires one of:
9. content resource read capability for `content://` workbook JSON (via resources/read), or
10. user-provided local workbook JSON file path.
11. Save/export capabilities are optional and independent:
12. if `oracle_analytics-save_catalog_content` is unavailable, run disk-first generation + validation checks and return deterministic disk-only outcome
13. if save is available but `oracle_analytics-export_workbook` is unavailable, proceed with save + `viewUrl` and skip export
14. Export is opt-in by user intent; default behavior is save + return `viewUrl` without export
## Required local assets
Resolve `<WB_SKILL_ROOT>` as the directory containing the active workbook-authoring `SKILL.md`. Common package paths:
1. `.agents/skills/workbook-authoring` (Codex full zip layout)
2. `.codex/skills/workbook-authoring` (Codex full zip layout)
3. `skills/workbook-authoring` (local skill/plugin install layout)
4. fail fast if none exist
1. `<WB_SKILL_ROOT>/<TARGET_VERSION>/templates/template-index.json`
2. `<WB_SKILL_ROOT>/<TARGET_VERSION>/templates/*.json`
3. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/metadata-to-json-mapping.v1.json`
4. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/filter-profiling-contracts.v1.json`
5. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/calculation-contracts.v1.json`
6. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/version-field-catalog.json`
7. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/runtime-profile-contracts.v1.json`
8. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/semantic-validation-rules.v1.json`
9. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/plugin-type-aliases.v1.json`
10. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/viz-runtime-catalog.v1.json`
11. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/viz-resolution-profiles.v1.json`
12. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/presentation-polish-contracts.v1.json`
13. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/edit-operation-contracts.v1.json`
14. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/support-window.v1.json`
15. `<WB_SKILL_ROOT>/tools/runtime-validation-check.mjs`
16. `<WB_SKILL_ROOT>/tools/modify-workbook.mjs`
17. `<WB_SKILL_ROOT>/tools/regenerate-workbook.mjs`
18. `<WB_SKILL_ROOT>/tools/validate-requirements-trace.mjs`
19. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-contract.v1.json`
20. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-adapter-contract.v1.json`
21. `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/validation/schema-registry-profile.json`
22. `<WB_SKILL_ROOT>/<TARGET_VERSION>/schemas/workbook-schema-manifest.json`
23. `<WB_SKILL_ROOT>/<TARGET_VERSION>/schemas/*.js`
24. In multi-version installs, choose `<TARGET_VERSION>` from installed folders under `<WB_SKILL_ROOT>/` (minimum supported `26.01`).
## Required workflow
### 1) Parse intent
Capture:
1. visual type
2. business question
3. dimensions/measures/time fields
4. filters and layout expectations, including expected canvas count, viz distribution per canvas, and canvas names when known
5. whether user intent is update existing workbook vs create new workbook
6. whether detailed traces were explicitly requested (`trace`, `debug`, `diagnostics`, or `traceRequested=true`)
### 2) Save target resolution (required)
1. Keep generation policy fixed: regenerate complete workbook JSON from requirements.
2. Detect save capability first:
3. if `oracle_analytics-save_catalog_content` is unavailable, skip remote target resolution and continue with disk-only output.
2. Resolve save mode from user intent:
3. `replace_existing` when user asks to change/update an existing workbook (default for update intent).
4. `create_new` only when user explicitly asks for a new workbook/copy/variant.
5. Resolve target workbook by capability:
6. use `oracle_analytics-search_catalog` when available.
7. else use `oracle_analytics-discover_data` only for metadata discovery and do not attempt remote save target resolution.
6. In `replace_existing` mode:
7. require exactly one resolved workbook target (`id`).
8. if unresolved or ambiguous, fail fast with actionable message (do not silently create a new workbook).
9. In `create_new` mode:
10. create with `parentId` + `name`.
11. 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)
1. Route request to `regenerate_workbook` unless intent clearly requests a supported scoped modify operation.
2. `modify_existing` supports only:
3. edit existing filter operator/default/source values.
4. add filter-bar filter for an existing criteria column.
5. edit workbook/canvas/view titles; if title path is missing, create canonical path and then apply title update.
6. Route to `modify_existing` only when one source path is available:
7. catalog content read for `content://`, or
8. user-provided local workbook JSON file path.
9. If neither source path is available, fail with actionable guidance to download workbook JSON to disk and provide file path.
10. Unsupported modify intents must fail with actionable `not supported in modify_existing mode`.
11. Keep `regenerate_workbook` flow unchanged as primary path.
12. Execute primary regenerate flow through the bundled driver:
```bash
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 **beside `bundle.yaml`** (mirrors
> `overlays/<name>/` and `profiles/`):
> - `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.json` and
> `--output workbooks/<name>/workbook.json` when the caller doesn't specify
> paths. **Do not commit the raw `workbook.json` or any `*bound*` request** —
> they carry the OAC host / dataset UUID / session tokens; the bundle
> `.gitignore` ignores `workbooks/**/workbook*.json` + `workbooks/**/*bound*.json`
> (allowing `*.redacted.json`). Never write to `/tmp` (lost on reboot) or into
> `tests/live/` (that path is for skill *evidence*, not user work).
13. Build request payload to satisfy `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-contract.v1.json`.
14. Build `adapterPayload` to satisfy `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/regenerate-workbook-adapter-contract.v1.json`.
15. For `compose_ootb`, include approved `analysisRequirements` before generation:
16. required gate: `brief -> discovery/profile -> requirements artifact -> explicit approval -> generate`.
17. `analysisRequirements.approval.status` must be `approved`.
18. Treat `analysisRequirements` as the single approved story/spec planning artifact. Do not introduce a separate YAML or compact-spec runtime.
19. `analysisShape` and `adapterPayload` are supporting execution inputs: `analysisShape` may be explicit, or it may be bootstrapped from `analysisRequirements.canvases`; `adapterPayload` remains the datasource/profile evidence.
20. `analysisRequirements` may 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.
21. `analysisRequirements` must align with `analysisShape` canvas/view IDs when both are provided.
22. each compose view must include detailed planning (`purpose`, `grain`, `bindings`, `labels`, `filters`, `calculations`, and `sort`, optional `interactions`) or supported shorthand that normalizes to those fields.
23. supported view shorthand includes simple `type` / `viewType` / `visualization` values plus fields such as `x`, `y`, `category`, `value`, `metric`, `rows`, `columns`, `location`, and `filter`.
24. exact `pluginType`, explicit semantic-role `bindings`, exact calculations, interactions, and full data action metadata remain valid advanced planning; shorthand must not replace detailed planning when exact runtime shape is known.
25. unsupported shorthand or conflicting shorthand vs explicit bindings must fail fast; do not silently substitute another visualization.
26. each normalized `analysisRequirements.canvases[].views[].filters[]` entry must include:
27. `filterID`, `columnID`, `location`, `scope`, `operator`, `default`, `planningOutcome`.
28. compose preflight lint behavior is controlled by optional `composeFilterTolerance.mode`:
29. default `strict`: missing filter fields fail fast with JSON-pointer diagnostics (for example `/analysisRequirements/canvases/0/views/0/filters/0/scope`) before generation starts.
30. optional `tolerant`: missing `scope` auto-fills to `global`; missing `default` is derived from `adapterPayload.profiling.filterDecisionTrace.derivedDecisions` when possible; if derivation is not possible, fail fast with deterministic diagnostics.
31. regenerate output includes `composeFilterToleranceSummary` with mode and auto-fill telemetry.
32. minimal valid filter object shape:
33. `{"filterID":"flt_year","columnID":"dim_time_year","location":"filter_bar","scope":"global","operator":"in","default":["2025"],"planningOutcome":"applied"}`
34. Recommend (do not require) `analysisShape.canvases[].name` during initial generation so canvas titles are created correctly in one pass.
35. If canvas names are omitted, generation remains valid and titles can still be edited later.
36. Set `generationStrategy` explicitly for deterministic routing:
37. prefer `compose_ootb` by default for new workbook generation.
38. use `passthrough_bound` only when one of these is true:
39. the user explicitly asks to use an existing workbook and modify/preserve its current structure, or
40. the user asks to modify a previously `compose_ootb`-generated workbook using that workbook as bound input.
41. Do not let bound input presence alone (`adapterPayload.binding.boundWorkbookJson|boundWorkbookPath`) force passthrough in agent routing; set `generationStrategy="compose_ootb"` unless a passthrough condition above applies.
42. If `generationStrategy="auto"` is used, runtime routing is deterministic and will choose `passthrough_bound` whenever bound input exists; avoid `auto` for new-generation flows.
43. `passthrough_bound` requires bound workbook input and should not be blocked by OOTB topology limits.
44. `request.workbook.name` / `request.workbook.description` are save-layer metadata inputs only; do not persist them in workbook `content.json`.
45. Consume regenerate response `saveMetadata` for save-layer handoff (`name` / `description`) when save is attempted.
46. requirements trace uses severity split:
47. blocking mismatches (for example unresolved bindings/filters/calculations/placeholders) fail compose.
48. warnings (for example title caption mismatch) are returned in `requirementsTraceSummary.warnings` and do not block.
### 4) Modify-existing mode contract (when routed to modify_existing)
1. Source acquisition gate (required):
2. prefer catalog JSON read (`content://`) when available.
3. otherwise require user-provided local workbook JSON file path.
4. if neither source path is available, fail with actionable guidance (download workbook JSON and provide file path).
5. Resolve workbook target via catalog (`id`/path/name) for remote replace flows. If ambiguous, fail with candidate list and do not write.
6. Require explicit confirmation before every modify write.
7. Source mode defaults to catalog JSON read (`content://`).
8. Same-session fast-path bypass is allowed only when all are true:
9. same-session artifact path exists.
10. session artifact workbook id is present.
11. session artifact workbook id equals resolved target id.
12. On fast-path version/concurrency conflict, fail immediately (no auto-read fallback).
13. Apply deterministic mutator via `<WB_SKILL_ROOT>/tools/modify-workbook.mjs` with `--operation` set to a supported operation id from `<WB_SKILL_ROOT>/<TARGET_VERSION>/model/edit-operation-contracts.v1.json`.
14. Add-filter operation requires `columnID` already present in `criteria.columns.children`; if omitted canvas scope defaults to all canvases.
15. Title-edit operation may create missing canonical title paths (`viewCaption.caption.text`) before applying updates.
### 5) Metadata discovery
1. Choose discovery method by tool capability:
2. use `oracle_analytics-find_matching_datasources` first for natural-language datasource shortlist when available.
3. use `oracle_analytics-search_catalog` to resolve and validate `datasets` and `subjectAreas` authoritatively.
4. otherwise use `oracle_analytics-discover_data` only as compatibility fallback when newer discovery tools are unavailable.
Ver no GitHub