Skip to content

fix(teaching): manifest actions ARE discoverable + textField reads 'text' — drop two stale host caveats - #5

Merged
acebytes merged 1 commit into
mainfrom
teaching-manifest-actions-textfield-accuracy
Aug 14, 2026
Merged

fix(teaching): manifest actions ARE discoverable + textField reads 'text' — drop two stale host caveats#5
acebytes merged 1 commit into
mainfrom
teaching-manifest-actions-textfield-accuracy

Conversation

@acebytes

Copy link
Copy Markdown
Contributor

Fixes two stale host caveats in the teaching sources, flagged by codex on AppOS-Desktop PR #141 (https://github.com/acebytes/AppOS-Desktop/pull/141) against the generated plugin-factory-context.md.

1. Manifest actions.definition contributions ARE discoverable (stale fn-163 caveat)

The bundle taught that manifest-declared actions "never reach discovery (host bug fn-163)". Verified against the shipped Desktop host: Sources/TwoPanez/Services/Plugins/CorePlugins/ActionsPlugin/ActionsRegistryCorePlugin.swift performs cold-start replay of manifest actions.definition contributions into DiscoveryStore (replayManifestDefinitionContributions, call sites at ~739-749 cold start and ~511-522 re-activation, impl at ~1878) plus lifecycle re-ingestion via the contributor lifecycle subscription. Tests/TwoPanezTests/Actions/ActionsRegistryCorePluginTests.swift asserts qualified- and bare-form manifest contributions land in DiscoveryStore at cold start, surface via the merged actions.all() / palette.query() catalog, are replayed for .resolved contributors at production boot shape, and are never resurrected for disabled contributors.

Teaching now retains the merged-catalog contract: manifest-only entries ARE discoverable (badged "manifest only" in the Action Browser) and surface ACTION_NOT_FOUND on invoke until runtime register() / registerFromCommand() binds the handler. Dual registration remains the shipped pattern; the rationale is corrected from "manifest never reaches discovery" to "manifest = discoverable metadata, runtime = executable handler".

2. textField reads typed text (obsolete value workaround)

The bundle claimed the host reads only value, so typed text "renders empty", and taught an assertion-cast dual-key workaround. Verified against the shipped Desktop renderer: Sources/TwoPanez/Services/Plugins/PluginViewDescriptorRenderer.swift lines 230-232 on main (fn-179, commit b18064e85) read properties["text"] FIRST with legacy loose-JSON properties["value"] as back-compat fallback only. Teaching now documents text as the supported initial-contents property and drops the workaround.

Touched surfaces

  • reference/extension-api.md — both flagged compile regions (ctx.actions catalog prose + extensions[] blockquote + all() table row + ctx.palette paragraph, and the textField bullet)
  • reference/patterns.md §3 (dual-registration pattern, no longer titled "fn-163 workaround")
  • SKILL.md, skills/viewdescriptor-authoring/SKILL.md, agents/plugin-architect.md, commands/new-plugin.md, README.md — same two corrections on non-compiled surfaces
  • compiled/ artifacts + manifest.json regenerated via AppOS-Desktop scripts/compile-factory-context.sh

Gates

  • npm run check green (freshness + verify-knowledge 69 fences + compiled-freshness)
  • Compiled context 179067 bytes — under the 179200-byte (175 KB) ceiling
  • Desktop ./scripts/compile-factory-context.sh --check green; swift test --parallel --filter 'E2EFactoryContextResourceTests' green

Merge order

This PR must merge BEFORE AppOS-Desktop PR #141 — #141's regenerated bundle asserts freshness against dev-plugin main (same ordering as the previous URL-contract round, PR #4).

…ext' — drop two stale host caveats

Two shipped-host behaviors were still taught as bugs/workarounds:

1. Manifest 'actions.definition' discovery (stale fn-163 caveat).
   The host's ActionsRegistryCorePlugin replays manifest contributions
   into DiscoveryStore at cold start and on plugin activation
   (replayManifestDefinitionContributions, ActionsRegistryCorePlugin.swift
   ~739-749 cold start / ~511-522 re-activation), and
   ActionsRegistryCorePluginTests verifies the stubs surface via the
   merged actions.all() / palette.query() catalog. Teaching now retains
   the merged-catalog contract: manifest-only entries ARE discoverable
   (badged "manifest only"), and become executable once runtime
   register() binds the handler. Dual registration stays the pattern —
   the rationale is now "manifest = discoverable metadata, runtime =
   executable", not "manifest never reaches discovery".

2. textField initial contents (obsolete 'value' workaround).
   The host reads properties["text"] first with legacy properties["value"]
   as back-compat fallback only (PluginViewDescriptorRenderer.swift
   ~230-232, fn-179 commit b18064e85). Teaching now documents 'text' as
   the supported property and removes the assertion-cast dual-key
   workaround.

Touched: extension-api.md (both flagged regions + all() table row +
palette paragraph + extensions[] blockquote), patterns.md par.3, SKILL.md,
viewdescriptor-authoring/SKILL.md, plugin-architect.md, new-plugin.md,
README.md, plus regenerated compiled/ artifacts (npm run check green;
compiled context 179067 bytes, under the 179200-byte ceiling).
@acebytes
acebytes merged commit 3c3b960 into main Aug 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant