Skip to content

fix(spec): retire the never-built typed-event system; the lifecycle registry now lists the events that actually fire - #4241

Merged
os-zhuang merged 2 commits into
mainfrom
claude/plugin-boot-logs-visibility-12kkwh
Jul 30, 2026
Merged

fix(spec): retire the never-built typed-event system; the lifecycle registry now lists the events that actually fire#4241
os-zhuang merged 2 commits into
mainfrom
claude/plugin-boot-logs-visibility-12kkwh

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

What

Follows up the #4212 leftovers (ADR-0049 enforce-or-remove): the lifecycle-event surface promised a typed-event system that was never built, in three layers. -1164/+235.

Deleted kernel/plugin-lifecycle-events.zod.ts — 346 lines of event payload schemas + a 21-name enum. Zero consumers for every export (verified per-name repo-wide, including apps/examples). The enum was wrong in both directions: 17 names nothing fires, and 10 real events missing.

Rewrote contracts/plugin-lifecycle-events.tsIPluginLifecycleEvents kept the same 17 dead names next to 5 real ones, plus an ITypedEventEmitter nothing implements. It is now the registry of the 14 events with a real emitter, each payload as observed at its fire site:

EventEmitter
kernel:ready / kernel:bootstrapped / kernel:listening / kernel:shutdownboth kernels
app:seededruntime AppPlugin (inline seeder)
metadata:reloadedmetadata plugin (artifact watcher) — metadata now optional, matching the documented contract
external.schema.driftexternal-validation plugin
ai:routescloud AI service plugin (out-of-repo emitter; in-repo listener in DispatcherPlugin)
auth:configureplugin-auth (mutate-in-place config extension point)
mcp:ready, automation:ready, analytics:ready, external-datasource:ready, datasource-admin:readythe {service}:ready convention family

The load-bearing kernel:bootstrapped / app:seeded doc blocks (#2996 ordering caveats) are preserved verbatim.

Enforcement so it cannot rot again

  • LifecycleEventName now types PluginContext.hook/trigger in @objectstack/core as LifecycleEventName | (string & {}) — known names autocomplete; custom cross-plugin names stay legal (the bus is open by design; zero breakage).
  • A pinning test asserts two-way equality (compile-time Exclude-to-never both directions + runtime list) between the interface keys and the fire-site inventory, each name annotated with its emitter.

Guard-rail edits made deliberately in this PR

  • json-schema.manifest.json −13 keys and authorable-surface.json −33 lines: both guards' sanctioned same-PR deliberate-removal path. Note for reviewers: these keys were never authorable — they described runtime event payload records no config author can write, so the silent-strip class the authorable-surface ratchet guards against is vacuous for them. If you'd rather see the full retiredKey() + D2 conversion treatment anyway, say so and I'll add it.
  • SKILL_MAP entry dropped (the concept's skill coverage is the hand-written references/plugin-hooks.md, which already documents exactly this inventory and corroborated two events my first grep pass missed).
  • Generated docs regenerated via gen:docs / gen:skill-refs; PROTOCOL_MAP.md row repointed at the contracts registry.

Verification

  • spec: 7142 tests green (275 files), tsc --noEmit clean
  • core: 437 tests green, builds
  • Full generated-artifact gate family in sync: docs (251), skill refs/docs/examples (198 prose examples type-check), api-surface, authorable-surface, spec-changes, upgrade-guide, exported-any (1920 types)

Deliberately not done


Generated by Claude Code

…sts the events that actually fire
The lifecycle-event surface promised a typed-event system that was never
built, in three layers (#4212 leftovers, ADR-0049 enforce-or-remove):
- kernel/plugin-lifecycle-events.zod.ts: 346 lines of payload schemas +
a 21-name event enum — zero consumers for every export, and the enum
both listed 17 names nothing fires and missed 10 events that DO fire.
Deleted, with its test and barrel line; the 13 schemas leave
json-schema.manifest.json and authorable-surface.json in the same PR
(sanctioned deliberate-removal path; the keys were never authorable —
they described runtime event payloads no config author can write, so
the silent-strip class the ratchet guards against is vacuous here).
- contracts/plugin-lifecycle-events.ts: IPluginLifecycleEvents kept the
same 17 dead names alongside 5 real ones, plus an ITypedEventEmitter
nothing implements. Rewritten as the registry of the 14 events with a
real emitter — kernel:{ready,bootstrapped,listening,shutdown},
app:seeded, metadata:reloaded (metadata now optional, matching the
documented contract), external.schema.drift, ai:routes (out-of-repo
emitter, in-repo listener), auth:configure, and the {service}:ready
convention family (mcp, automation, analytics, external-datasource,
datasource-admin) — each with its payload as observed at the fire site.
- Enforcement so the registry cannot rot again: LifecycleEventName now
types IPluginContext.hook/trigger in @objectstack/core as
LifecycleEventName | (string & {}) — known names autocomplete, custom
cross-plugin names stay legal — and a pinning test asserts two-way
equality between the interface keys and the fire-site inventory.
Docs follow the code: the generated reference page for the deleted zod
file is gone (nav + index links updated via gen:docs), PROTOCOL_MAP row
repointed at the contracts registry, skill reference index regenerated.
Verified: spec 7142 tests green (275 files), core 437 green, spec tsc
--noEmit clean, and the full generated-artifact gate family in sync
(docs 251, skill refs/docs/examples, api-surface, authorable-surface,
spec-changes, upgrade-guide, exported-any).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HrRNgrWaRtggzmrHpbomyh
@vercel

vercelBot commented Jul 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredJul 30, 2026 6:17pm

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling and removed documentation Improvements or additions to documentation tests tooling labels Jul 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/core, @objectstack/spec.

114 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/actions-as-tools.mdx(via @objectstack/core)
  • content/docs/ai/agents.mdx(via @objectstack/spec)
  • content/docs/ai/knowledge-rag.mdx(via @objectstack/core)
  • content/docs/ai/natural-language-queries.mdx(via @objectstack/core)
  • content/docs/ai/skills-reference.mdx(via @objectstack/spec)
  • content/docs/ai/skills.mdx(via @objectstack/spec)
  • content/docs/api/client-sdk.mdx(via @objectstack/spec)
  • content/docs/api/environment-routing.mdx(via @objectstack/spec)
  • content/docs/api/error-catalog.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx(via @objectstack/spec)
  • content/docs/api/index.mdx(via @objectstack/spec)
  • content/docs/automation/approvals.mdx(via packages/spec)
  • content/docs/automation/flows.mdx(via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx(via packages/spec)
  • content/docs/automation/hooks.mdx(via @objectstack/spec)
  • content/docs/automation/index.mdx(via @objectstack/spec)
  • content/docs/automation/webhooks.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/automation/workflows.mdx(via @objectstack/spec)
  • content/docs/concepts/architecture.mdx(via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx(via packages/spec)
  • content/docs/concepts/index.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx(via packages/spec)
  • content/docs/concepts/north-star.mdx(via packages/core, packages/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx(via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx(via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx(via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx(via @objectstack/spec)
  • content/docs/data-modeling/index.mdx(via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx(via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx(via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx(via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx(via @objectstack/spec)
  • content/docs/deployment/cli.mdx(via @objectstack/spec)
  • content/docs/deployment/migration-from-objectql.mdx(via @objectstack/core)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx(via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx(via @objectstack/spec)
  • content/docs/getting-started/examples.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx(via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx(via @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx(via packages/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx(via @objectstack/core)
  • content/docs/kernel/runtime-services/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via packages/spec)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/kernel/services.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/permissions/authentication.mdx(via @objectstack/core)
  • content/docs/permissions/authorization.mdx(via packages/core, @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @objectstack/spec)
  • content/docs/permissions/positions.mdx(via @objectstack/spec)
  • content/docs/permissions/rls.mdx(via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx(via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx(via @objectstack/spec)
  • content/docs/plugins/anatomy.mdx(via @objectstack/core)
  • content/docs/plugins/development.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/plugins/index.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx(via @objectstack/spec)
  • content/docs/protocol/diagram.mdx(via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.mdx(via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx(via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx(via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v12.mdx(via @objectstack/core, @objectstack/spec)
  • content/docs/releases/v13.mdx(via @objectstack/spec)
  • content/docs/releases/v15.mdx(via @objectstack/core)
  • content/docs/releases/v16.mdx(via @objectstack/spec)
  • content/docs/releases/v17.mdx(via @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/spec)
  • content/docs/ui/actions.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @objectstack/spec)
  • content/docs/ui/forms.mdx(via @objectstack/spec)
  • content/docs/ui/index.mdx(via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx(via @objectstack/spec)
  • content/docs/ui/setup-app.mdx(via @objectstack/spec)
  • content/docs/ui/translations.mdx(via @objectstack/spec)
  • content/docs/ui/views.mdx(via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Jul 30, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review July 30, 2026 19:15
@os-zhuang
os-zhuang merged commit 7777e8f into mainJul 30, 2026
25 of 27 checks passed
@os-zhuang
os-zhuang deleted the claude/plugin-boot-logs-visibility-12kkwh branch July 30, 2026 19:15
os-zhuang added a commit that referenced this pull request Jul 31, 2026
… v17 notes and status matrix (#4279)
* docs(releases): record the #4212-family plugin-API retirements in the v17 notes and status matrix
The v17 release notes already carried the #4212 row (lifecycle-hook family)
but not its two follow-ups that also ship in the 17.0.0 train:
- "Dead spec clusters removed" gains the #4241 row: the never-built
typed-event cluster (ten payload schemas, the 21-name enum wrong in both
directions, ITypedEventEmitter), and what replaced it — the enforced
IPluginLifecycleEvents registry of the 14 events with a real emitter plus
the LifecycleEventName soft union on hook/trigger.
- "Smaller breaking changes" gains the #4242 entry: ObjectQLEngine.use() /
ObjectQLHostContext removal, with the FROM → TO migration (registerApp /
kernel plugin) and the explicit note that the app-bundle onEnable module
export is a different, live contract.
implementation-status.mdx stops claiming "lifecycle hooks" as a plugin-system
capability (that family never ran and is now retired) and states the real
init/start/destroy contract and the #4241 event registry instead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HrRNgrWaRtggzmrHpbomyh
* chore: empty changeset for the docs-only release-notes update
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HrRNgrWaRtggzmrHpbomyh
---------
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xlteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-zhuang@claude