Roadmap¶
Reviewed 2026-09-30 against dd79a4a (v0.4.2). This run has owner authorization
for bounded feature work. Estimates are engineering days including tests and docs,
not delivery dates. Evidence below distinguishes code findings from vendor claims.
Baseline¶
Read CLAUDE.md, CONTRIBUTING.md, README, changelog, security policy, published
guides, historical design documents, package code, tests and GitHub workflows.
Windows, Python 3.12.14; uv sync --extra dev --extra ai --extra mcp succeeded
with uv 0.12.21 installed locally for this audit. Added the docs extra for its CI
check. Locked SDKs: Anthropic 0.89.0 and MCP 1.27.0.
| Check | Baseline result |
|---|---|
uv run ruff check src/ tests/ |
Passed |
uv run pytest -v |
Initially 85 passed / 21 temp-directory permission errors; 106 passed with fresh workspace temp paths |
uv build |
Wheel and source distribution built |
uv run mkdocs build --strict |
Passed |
Fixture extraction and validate --exit-code |
17 elements, 21 events, no drift |
ci.yml runs lint, build and tests on Ubuntu/Windows with Python 3.11–3.13.
docs.yml runs the strict docs build. No repository workflow invokes the composite
drift action; its offline CLI equivalent was run additionally. Hosted matrix jobs,
live authentication, paid inference and Amplitude writes were not exercised.
No design cache or credential-bearing config was opened.
Now¶
Completed in this run, bugs before the final small detection feature. Each implementation commit received regression coverage and the full local CI check set.
| Item | Why it matters | Evidence | Effort | Risk |
|---|---|---|---|---|
N1. Correct Figma URL parsing, disable both cache reads and writes with --no-cache, and explain auth/rate errors |
Fetch the selected branch and avoid persisting private designs when explicitly disabled | Baseline figma_client.py:27–36 matches the parent before the branch; :99 writes unconditionally; no client tests. Authentication, rate limits |
1 | Low; malformed inputs become errors |
| N2. Detect named non-component nodes with prototype interactions | A frame called Button must not disappear when a generic clickable frame is detected | Baseline extractor.py:147–150 requires a missing name match for non-components. Add a synthetic interaction fixture |
0.5 | Low; more expected events |
| N3. Honor naming pattern/style and apply the configured cap and screen action to pageviews | Config must govern generated names, including long screen names | Baseline taxonomy_engine.py:38 hardcodes the pattern; :149 bypasses the cap and screen action; test_config.py already accepts camelCase |
1 | Medium; previously ignored settings change names; collision policy remains an open question |
| N4. Make Amplitude dry runs offline and correct event category payloads | Preview must work without credentials; categories must arrive on the event | Baseline amplitude_push.py:70 GETs before dry-run; event POST uses category_name instead of documented category. API |
0.5 | Low; mock exact bodies and reject API-declared failures |
| N5. Make MCP extraction results usable by export and validate; align page filtering | An implementer should be able to connect the advertised tools without rewriting JSON | Baseline mcp_tools.py returns an event list but consumers require a map; tests manually convert it. Missing/excluded page behavior differs from CLI |
1 | Low; accept both existing shapes |
| N6. Correct AI price estimates and the added-property count | Users need a credible billable-run preview and accurate result | Baseline ai_enricher.py:23 overprices Opus 4.6; unknown models silently use Haiku rates; CLI counts after mutation. Pricing |
0.5 | Low; preserve opt-in behavior |
| N7. Carry source node IDs into CSV and Excel review exports; correct import claims | Reviewers need the source design in every output, not only JSON/Markdown | output/amplitude_csv.py, output/excel.py omit IDs. Current six-column CSV differs from the Data import schema |
0.5 | Medium; additive columns affect positional consumers |
| N8. Discover screen frames inside Figma sections | Teams organize screens in sections; those screens currently vanish | Baseline _find_screens reads direct page frames only. SECTION node. Add a nested-section fixture; retain current variant semantics |
0.5 | Low; additional screens appear |
Completed follow-up: multiple-source provenance¶
Implemented after the owner's request to start the roadmap tasks. Every variant frame is now visited, identical full event names retain all contributing control IDs, and variant-only controls produce events. Names that collide only after truncation fail with instructions to change the cap, pattern or control names.
The compatibility contract is additive: source/source_node_id remains the
first contributing ID, with sources/source_node_ids storing the full list.
CSV/Excel append a JSON-array Source Node IDs column; Markdown lists all IDs.
Description/category selection remains unchanged. Optional AI groups each shared
event once and preserves its sources. Drift compares source membership and uses
any shared ID for unambiguous renames; ambiguous splits/merges are not guessed.
Migration: regenerate and review new events and source additions before updating the stored baseline. Legacy single-source files still load.
Completed follow-up: screen identity and pageview provenance¶
Controls retain their owning page ID and frame ID. Categories come from each
control's page, removing the last-page-wins screen-name map. Existing naming stays
the default; {page} is an optional normalized page-name placeholder. If different
pages generate the same event name, extraction fails with guidance to qualify the
pattern or rename screens/pages. Distinct page IDs never merge just because page
names match. Control/pageview name collisions also fail with naming guidance.
CLI and MCP use a separate screen inventory to emit pageviews for empty screens
and retain every variant frame's ID. Included pages and section traversal follow
the same rules as control extraction. Existing two-argument Python generation is
compatible but cannot discover empty frames; callers pass screens=extract_screens(...)
for the full inventory. Missing IDs in hand-built inputs are not fabricated.
Migration: expect new pageview sources and empty-screen events. Review those
additions before accepting a regenerated baseline. Frame sources support pageview
rename detection, and category-only changes now fail drift checks. Naming patterns
with cross-page collisions need {page} or distinct design names; no automatic
prefix is added based on the current page filter.
Completed follow-up: Amplitude Data CSV profile¶
Added opt-in amplitude-csv to CLI/config/MCP, keeping the review csv and
default formats unchanged. The profile pins all 33 public import headers in a
synthetic fixture derived from the published schema
on 2026-09-30. No authenticated template was downloaded and no real project was
imported; account/UI acceptance remains unverified.
Rows preserve event-specific property associations, categories and descriptions.
Simple types, integers and non-empty string enums are supported; unrepresentable
constraints and ambiguous enum delimiters fail before writes. Each CSV has a
mandatory sibling JSON with full Figma sources and original supported schemas.
The import does not misuse Amplitude's Event source for node IDs. JSON writing
now explicitly uses UTF-8. Import notes explain that blank owners clear existing
owners, and that blank action creates/updates entities. Remote metadata is not
preserved by this initial-plan profile; review the import branch before merging.
Completed follow-up: repeatable Amplitude API push¶
Push now reads categories, events and event-scoped property inventories before
writing. It creates only missing definitions, with events before their property
associations. Property requests always include event_type, including the form
body on scoped GETs documented by the Taxonomy API.
The same property name can have different schemas on different events. Supported
string enums retain their values, and local unsupported types/constraints fail
before requests, including offline previews.
The update policy is create-only: matching definitions are reused, while event category/description and property type/description/enum conflicts are reported without overwriting them. No shared-definition updates, lifecycle operations or automatic retries of failed writes were added. A 409 gets one inventory read and is accepted only when a matching definition is visible. Initial inventory errors block all writes; later failures block dependent writes and permit independent events to continue. Reruns fill missing associations after partial failures.
Migration: existing plans pushed by the earlier global-property implementation may need missing associations. Review conflicts manually. CLI counts now report event/property associations; the Python result retains legacy unique property names and adds precise association lists. Unmodeled remote metadata is left untouched. Live account acceptance remains unverified.
Completed continuation (2026-10-01)¶
Owner authorized completion of the remaining Next and Later work on 2026-10-01.
Work continues on roadmap-work after the previous 14 commits were merged and
pushed to master. Non-goals and offline-only service testing remain in effect.
Completed in this continuation: property schema drift. Reports include type,
description and enum changes, preserving enum set semantics and following source
renames. File-to-file diffs also compare extra stored constraints without dropping
them during hydration. CLI and MCP expose an additive property_schema_changes
field; property-name additions/removals retain their existing shape.
Completed: Figma request efficiency and bounded retries. A cold/expired fetch makes one file request; extraction can reuse a five-minute local cache while validation defaults to fresh data. CLI/MCP expose cache age, explicit offline use and disabled caching. Three attempts and ten seconds of total retry waiting bound transient GET recovery; server delays are never shortened. Synthetic cache tests use isolated temp directories, never the repository's design cache.
Completed: configuration validation and previously ignored options. YAML errors identify paths/lines, types and unknown keys fail before extraction, output paths honor config unless explicitly overridden, and disabled label fallback reports the node requiring text. Screen max-depth is explicitly reserved at its legacy value 2; unsupported values are rejected rather than assigning new screen semantics. Nested default property/rule definitions are independent between config instances.
Completed: review exports and Windows text I/O. Excel has an additive complete event/property detail sheet with types, enums and sources while retaining its legacy overview. Design strings are explicit text cells; values Excel would truncate or cannot encode fail before saving. Config, fixture, cache and taxonomy JSON reads use UTF-8; CSV retains original strings without changing event names.
Completed: optional enrichment hardening. Malformed containers/types are ignored; suggestions only target their originating batch. All batches are planned before calls with event-count and prompt-character limits, and the preview uses that same plan. Truncated/missing responses fail without partially mutating the taxonomy. Paid calls remain opt-in and all verification uses mock clients.
Completed: plan-token authentication, plus acceptance of externally issued OAuth
access tokens. FIGMA_TOKEN_TYPE selects PAT/plan headers or OAuth bearer auth;
tokens remain environment-only. This takes the plan-token alternative in the
proposal without building an OAuth callback service or credential lifecycle.
Issuance, rotation/refresh and account entitlement remain external and unverified.
Completed: MCP 1.x upgrade and separate 2.x evaluation. The optional requirement
is now mcp>=1.30,<2, locked at 1.30.0. The real stdio protocol test covers session
initialization, discovery, fixture extraction, JSON export, validation, schema
drift and invalid tool arguments. Evaluation of the 2.x migration guide
confirms FastMCP import removal, renamed model fields and HTTP dependency changes;
retain the maintained 1.x line for this release. A major migration is not implied
by completion of its evaluation and remains a separate future release decision.
Completed: detection fixture coverage and explicit policies. The synthetic
detection_policy.json covers nested labels, nested controls, icon-only CTAs,
hidden controls/sections, instance variant properties and legacy transitions.
Nested labels and legacy interactions are detected; variant values are retained
on elements. Hidden inclusion and parent suppression preserve legacy defaults,
with explicit options to exclude hidden subtrees or collect nested controls.
Decorative exclusions still win unless overridden in the next item.
Completed: configurable detection overrides. Ordered, typed config rules select case-insensitive name globs or exact node IDs; the first match determines include type or subtree exclusion. Visibility and ancestor traversal boundaries stay explicit. Tests cover icon-only CTAs, custom component names, precedence, hidden nodes and invalid rules without changing the naming engine's configurability.
Completed: optional detection explanation reports. CLI --explain PATH and MCP
explain=true expose a versioned record for every supplied node, including
excluded and suppressed descendants, rule matches, variants and actual generated
event names. Shared classification keeps decisions aligned with extraction;
reports do not alter event output. Tests cover provenance, traversal, opt-in
behavior and protection against overwriting taxonomy output with a report.
Next¶
No unfinished implementation items remain from the roadmap authorized on 2026-10-01. Service verification used fixtures and mocks; real-account import acceptance remains unverified and requires a separate live-service decision.
Later¶
The original Later item (detection explanations) is complete. The owner then explicitly requested MCP 2 migration and OAuth lifecycle support; both are implemented in the follow-up below. New screen-depth semantics remain a future product decision.
Research notes¶
Sources accessed 2026-09-30; vendor docs describe contracts, not a live-account test.
- Figma:
file_content:readis the relevant scope; legacy OAuthfile_readis deprecated (scopes). File/tree and node endpoints remain Tier 1. Limits depend on seat and resource plan, not a universal 60/min. The current rate-limit page's table and prose disagree on low-seat monthly quotas (20 versus 6); reportRetry-Afterrather than hardcode either number. Dev/Full table entries reach 10/15/20 requests per minute on paid plans (limits). The repo does not use the nodes endpoint; its claimed universal 50-ID maximum was not established by the current endpoint reference.interactions,SECTIONandtransitionNodeIDremain documented (node types). Recent color/stroke additions do not affect fields consumed here. Deprecated project endpoints were replaced by folder endpoints, which this client does not call (changelog). - Amplitude: the current reference covers planned schemas, Basic auth and the existing US/EU hosts. The old assertion that this is only an obsolete Govern API is unsupported. Current documentation does not establish universal plan entitlement; confirm access for the target project. A 2025 release note mentions Enterprise customers, which is not proof of current exclusivity. The 64-character setting remains this project's default naming policy; a universal Amplitude event-name cap of 64 was not verified.
- Claude: default Haiku ID
claude-haiku-4-5-20251001remains listed. Current model overview also lists Sonnet 5.5 and Opus 5.5; do not silently upgrade paid runs (models). Standard input/output USD per million tokens: Haiku 4.5 1/5, Sonnet 4.6 3/15, Opus 4.6 5/25 (pricing). Calls are per flow, not screen; six calls at 800 output tokens already cost $0.024 on Haiku before input. Per-screen/app-size price promises are unreliable.Anthropic().messages.create(model, max_tokens, messages)remains documented (SDK). Model quality and actual token use were not tested with paid calls. - MCP: the server uses 1.x
FastMCP; 2.x is a separate migration, not a version-bound edit. The existing upper bound is appropriate pending that work (upstream guidance).
Comparable tools and rejected directions¶
| Tool | Verified public description | Implication here |
|---|---|---|
| Avo | Direct Figma frame/section/file import into Journeys, source links and reload, announced May 2026 (announcement) | The old “no Figma extraction” comparison is stale; focus on an inspectable local pipeline |
| Glazed | Figma-based AI suggestions and taxonomy reuse (product); describes Amplitude/Segment/Mixpanel integration (introduction) | Do not claim it lacks Amplitude integration; improve fixture-backed extraction and traceable exports here |
| Amplitude Event Planner | Amplitude's article describes the Figma planning workflow | Current plugin maintenance/features were not independently verified; do not claim a current feature gap from an old table |
| Ampli | Pulls a tracking plan into typed instrumentation and checks implementation (CLI) | Complement the downstream workflow; do not build a code generator |
Rejected for this run: a Figma plugin, tracking-plan lifecycle/branching service, code generation, real-time synchronization, and automatic AI enrichment. These cross explicit non-goals or introduce unsolicited paid calls. MCP 2 migration remains a proposal requiring contract decisions and broader tests. The separate CSV importer was implemented in an owner-authorized follow-up. Competing on unverified vendor shortcomings is also rejected. Small correctness and handoff improvements are the useful gap.
Initial execution report (2026-09-30)¶
Local branch: roadmap-work, created from master at dd79a4a. Version remains
0.4.2. No push, pull request, tag, publication or live service call was performed.
| Commit | Change | Tests passing before commit |
|---|---|---|
25b6532 |
Add the researched roadmap and navigation | 106 |
c5c1c0f |
Correct Figma branch fetching, cache controls and errors | 117 |
d0ca539 |
Detect named prototype controls on raw nodes | 118 |
51da373 |
Honor naming pattern/style, pageview action and cap | 125 |
9cdbf81 |
Make Amplitude previews offline and correct category writes | 127 |
95a7f63 |
Accept MCP extraction output in export/validation | 134 |
1d9f06a |
Correct optional AI estimates and result counts | 137 |
8b2bd31 |
Preserve source IDs in CSV/Excel review exports | 138 |
03c6368 |
Discover screens inside nested sections | 139 |
All rows also passed Ruff, package build, strict docs build, fixture extraction and offline drift validation. Each bug had a failing regression before its fix; the section fixture also failed against the previous discovery code. The banking fixture remains at 17 elements and 21 events with no drift. New fixtures cover named prototype nodes and nested sections.
Initial-run verification: 139 tests pass on Windows/Python 3.12.14. Ruff, source and
wheel builds, strict MkDocs and offline drift checks pass. The initial temporary
directory errors were environmental; no test expectations were weakened to fix
them. Runs used PYTEST_ADDOPTS to select fresh tests/.tmp/... paths and a
writable pytest cache. Check logs are retained outside the Git repository after
the final run.
Unverified: the other five CI OS/Python combinations; live PAT/branch permissions; actual account rate limits; current Amplitude entitlement and UI imports; paid model quality, token usage and model availability for an account; the Event Planner plugin's current maintenance. Vendor contract checks used public web documentation, not authenticated API calls. The runtime lockfile was not upgraded. At that stage, larger and ambiguous changes remained in Next/Later; their later completion is recorded above. No credential-bearing config or design cache was read or staged.
Follow-up verification: 160 tests pass, including 21 provenance regressions
covering shared/unique variant controls, all exports, legacy inputs, optional
mocked AI enrichment, source-only drift, renames, ambiguous splits/merges, and
truncation errors before writes. The new variant_sources.json fixture contains
only synthetic nodes. Twelve new tests failed against the prior implementation
before the fix. Ruff, package builds, strict MkDocs, fixture extraction and offline
drift validation also pass. The banking fixture now retains 18 controls in the
same 21 events, including the second login button's ID.
Screen-identity verification: 181 tests pass, with 21 additional regression
cases for cross-page conflicts, page-qualified snake/camel names, page filtering,
empty screens/variants, all export formats, pageview renames, legacy source-less
baselines, and category drift through CLI/MCP. Eight initial cases and the category
drift case failed against the previous behavior before their fixes. The synthetic
screen_identity.json fixture includes same-named screens on two pages, an empty
variant, a text-only screen in a section, and an excluded page. Ruff, package
builds, strict MkDocs and offline extraction/drift checks pass. The banking demo
still has 18 controls and 21 events, now with frame sources on every pageview.
Amplitude CSV verification: 209 tests pass, including 28 new profile cases.
Fifteen initial tests failed before implementation. Coverage pins the published
headers, per-event property schemas, enum serialization, integer flags, empty
events/plans, Unicode/quoted/multiline text, both MCP input shapes, companion IDs,
and rejection of unsupported constraints/duplicates before writes. CLI tests
cover configuration and explicit format selection, coexistence with the review
CSV, and no partial output on schema errors. Ruff, package builds, strict MkDocs
and offline drift checks pass. The new examples/amplitude-data pair is generated
from the synthetic variant fixture and validates without drift. No account import
or remote write was performed; the runtime lockfile and package version remain
unchanged.
Amplitude push verification: 254 tests pass, up from 209. Seventeen initial regressions failed against the earlier implementation. The 45 added cases cover event-specific schemas, enums, repeat runs without writes, partial-failure recovery, conflicts, one-read 409 reconciliation, malformed/failed inventories, dependent-write blocking, local schema rejection, source preservation and CLI preview/result counts. The inventory fixture is synthetic and every API request is mocked. Ruff, package builds, strict MkDocs, fixture extraction and offline drift checks pass. The banking fixture remains at 18 controls and 21 events; its offline push preview reports 77 event/property associations. No live push, dependency upgrade or package version change was made.
Continuation execution report (2026-10-01)¶
Completed all remaining original Next/Later proposals on roadmap-work, following
the previous merge to master at 92dfc83. Each implementation commit passed
Ruff, the full test suite, package builds, strict MkDocs, banking-fixture extraction
and offline drift validation.
| Commit | Completed work | Tests passing |
|---|---|---|
2eb06b0 |
Property schema drift, including stored constraints | 264 |
670537b |
Single-request cache misses, TTL/offline policy and bounded GET retries | 281 |
487797b |
Strict config validation, independent defaults, output/fallback settings | 299 |
f7f58a7 |
Complete Excel property schemas and literal text handling | 302 |
2e40a1e |
Bounded optional AI batches and validated, atomic suggestion application | 318 |
3fbc5d7 |
Explicit PAT, plan-token and externally issued OAuth token headers | 322 |
37f03a8 |
MCP 1.30 upgrade, real stdio integration test, separate 2.x evaluation | 323 |
c9ad6f9 |
Detection fixture coverage, nested labels, visibility and traversal policies | 326 |
24c3fc6 |
Ordered name/node include and exclude rules | 335 |
62c1ec6 |
Optional CLI/MCP node-decision and event-provenance reports | 338 |
Final verification: 338 tests pass, up from 254 at the start of this continuation (106 before the original audit). Windows/Python 3.12.14 was tested locally; the other hosted OS/Python combinations remain unverified. The banking fixture retains 18 controls and 21 events with no drift. Test caches and logs use synthetic data and are retained outside the repository after verification.
MCP is now locked at 1.30.0 within >=1.30,<2; the package version is unchanged.
MCP 2 was evaluated, not migrated. Plan-token support satisfies the alternative
authentication proposal; OAuth issuance/refresh remains external. Screen depth
remains reserved at 2 with explicit rejection of unsupported values. These are
documented scope decisions, not claims of implementing a new credential service
or a new screen hierarchy model.
All service tests were offline or mocked, including the local MCP subprocess. No paid inference, live account import/push, credential-bearing config or real design cache was used. Live entitlement, token permissions, import acceptance and paid model output quality remain unverified. This continuation is committed locally; it has not been pushed or released.
MCP 2 and OAuth follow-up (2026-10-01)¶
The owner explicitly requested the two previously deferred implementation decisions. This section supersedes the earlier decision to retain MCP 1.x and leave all OAuth token lifecycle operations external.
MCP now requires >=2.2,<3 and locks 2.2.0. Commit 7f5b241 ports server
construction to MCPServer, selects stdio explicitly and adapts SDK protocol
field access while retaining the public tool contracts. The real subprocess
integration test passes extraction, explanation, export, validation and errors.
The optional oauth extra provides browser login for the user's own Figma app,
S256 PKCE/state validation, a bounded loopback callback, native OS credential
storage, proactive refresh, one refresh/replay after 401, and status/refresh/logout
commands. Local processes coordinate session changes with a per-user file lock.
Explicit environment tokens take precedence and are neither stored nor refreshed.
OAuth is selected explicitly; fixtures and offline cache reads remain independent
of credentials. No app secret is bundled and no plaintext storage fallback exists.
See OAuth setup and MCP setup.
Verification: 386 tests pass, including 48 new OAuth cases using synthetic credentials, mocked Figma endpoints, an in-memory credential store and a real local callback listener. Tests cover PKCE/state, callback rejection/denial/timeout, token response validation, rotation, concurrent refresh, failures without secret disclosure, environment precedence and CLI flows. Ruff, source/wheel builds, strict docs, fixture extraction and clean drift checks pass on Windows/Python 3.12.14. CI now installs the OAuth extra across its existing OS/Python matrix.
No actual OS credential entry, live OAuth consent or Figma service was accessed. Native backend selection is unit-tested; real store permissions/unlock behavior and account/redirect acceptance remain live setup checks. The package version is unchanged; these changes are committed locally, without push or release.