# Capability Map

Choose an artifact app when the deliverable is a hosted dashboard, website,
private tool, or interactive app with a versioned `artifact-app.json` manifest.
The current runtime target is `aws_lambda_function_url`; supported languages are
Node and Python.

| Need | Artifact-native path | Do not infer |
| --- | --- | --- |
| Page, asset, or private app API | Declare a route. API routes live under `/_artifact/*`; use relative browser fetches such as `./_artifact/data/summary`. | Global `/api/*` access or root-absolute `/_artifact/*` fetches. |
| Read-only reporting or derived metrics | Declare bounded live SQL in `datasets[]`, with a matching `/_artifact/data/<name>` API route. | A database URL or direct database connection in runtime/browser code. |
| Narrow source count | Use a live `sourceBinding` with `access: "service_aggregate"` and `aggregate.type: "count"`. | Sum, average, joins, ratios, or custom aggregates through this binding. |
| Per-viewer customer rows | Use the `viewer` source-binding path. It requires a session and is currently limited to `resource: "customers"`, `emailField: "email"`. | General row-level authorization for arbitrary sources. |
| Third-party API | Use a declared Secrets Manager ARN and a server-side artifact route. | Browser credentials, ordinary env-var secrets, or direct vendor calls from the browser. |
| Simple LLM turn | Private server-side `/_artifact/api/*` route plus one bounded Bedrock `Converse` call. | Agent loops, tools, memory, streaming, history, or a caller-supplied model/API key. |
| Published customer documents | For a normal app, declare an exact `knowledgeBases[]` binding and read it through relative `./_artifact/knowledge/<alias>` list, search, and fetch routes. | Company Knowledge, a source binding, direct `/knowledge/*` delivery, a Knowledge Base bearer, provider/storage identifiers, draft content, or Knowledge Bases in a hosted MCP artifact. |
| MCP tools for Topline chat or Topline Coding Agent tasks | `kind: "mcp_server"` from `fastmcp-server`, with the one canonical `/_artifact/mcp` route. | A credential in artifact source, direct self-connection, self-approval, or bypass of Developer Access tool review. |
| Large or expensive report | A `precomputed` dataset backed by private tenant-scoped object storage and an enabled `refresh_live_cache` schedule. | Direct object URLs or a slow fallback query before the first successful warm. |
| New customer API ingestion | Data Sources build using the shared REST connector when it fits, otherwise a custom platform connector. With the Data Sources workspace on, the source becomes a data pipeline artifact when scheduled. | An artifact app that owns a credential, checkpoint, scheduler, or ETL loop. |
| Which tables sync and when | The source's data pipeline artifact: edit its `pipelineManifest` as a draft (`save_pipeline_artifact_draft`); a person publishes. | Changing scheduler jobs directly, or publishing, pausing or resuming from a coding task. |

## Artifact-native versus adjacent work

Artifact apps own their package, manifest, declared routes, UI, bounded
read-only datasets, runtime API code, and manifest-declared refresh contract.
They can use platform-provided viewer/session, data-query, secret-reference,
object-storage, and Bedrock capabilities only through those declarations.

Artifact-adjacent work is required when the source is not already available to
the approved read-only tools: connector onboarding, source synchronization,
catalog exposure, and upstream data quality/freshness. Stop with a data blocker
instead of adding a credential, unbounded query, or unsupported network path to
the app.

For a new customer API, this adjacent work is itself a first-class Data Sources
workflow: source and connection intake, secret-reference capture, table
approval, bounded sample sync, connector-owned materialization, catalog
registration, and a normal scheduled pipeline. With the Data Sources workspace
on, that source is represented by one data pipeline artifact whose
`pipelineManifest` names its tables and schedules; the platform objects above
stay the system of record for credentials, checkpoints, rows and runs. Any
other saved artifact may hold the human-readable build brief, but it cannot
substitute for those durable objects.

Platform-service work is outside the app package: IAM, Lambda/runtime
provisioning, database/source credentials, secret creation, raw scheduler jobs,
object-storage URLs, direct cloud deploys, and live promotion. An app can
declare what it needs; it does not grant itself those platform capabilities.

## App shape

Pick the manifest `kind` that matches the result: `dashboard`, `mini_page`,
`briefing`, `table`, `tool`, or the app-only `mcp_server`. Every v2 manifest declares its
runtime, build, validation commands, routes, source bindings (possibly empty),
environment names, and `viewerPolicy` (`private` or `tenant`). Datasets and
refresh schedules are optional only when the app does not need them.

Use the manifest as the boundary: each dataset name contains only letters,
numbers, underscores, or hyphens and maps exactly to
`/_artifact/data/<name>`; each route is declared once. Set maximum rows, bytes,
timeout, and rate/cache settings appropriate to the displayed result rather
than treating the app as a general query client.

`mcp_server` is the deliberate exception to the ordinary artifact data shape:
its `sourceBindings`, `datasets`, and `refreshSchedules` must be empty. Its
machine credential authorizes only the exact live MCP route, not a callback to
artifact data routes. Use approved `secretBindings` for server-side external
APIs or move Topline-owned data and recurring work behind a reviewed platform
service.
