You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Module.preview() + PreflightResult.predicted_changes (PROTOCOL_SPEC v0.21.0 §5.6 / §12.8 — promoted from RFC apcore/docs/spec/rfc-preview-method.md, apcore commit c191b85) — New optional preview(inputs, context) method on the Module Protocol. Modules implementing preview() return a PreviewResult (or None when prediction is unavailable) whose changes list is a structured prediction of the state changes the call would produce — answering the AI-orchestrator-driven question "if I were to call this module with these inputs, what would change in the world?". Detection mirrors the existing preflight() optional-method pattern (hasattr(module, "preview") and callable(module.preview)). Executor.validate() invokes the method (awaiting the result if it's a coroutine — both sync and async implementations are supported), folds PreviewResult.changes into the new PreflightResult.predicted_changes field, and records a module_preview advisory check on PreflightResult.checks. Exception semantics match preflight(): a raised exception is surfaced as a warning on the module_preview check and does not fail validation. New Change and PreviewResult pydantic models exported from the top-level apcore package. Change uses the Python idiomatic encoding called out in the RFC's "Change.x-* extension fields" cross-SDK schema-encoding table — pydantic.ConfigDict(extra='allow') paired with a model-validator that rejects extra keys not matching ^x-, mirroring the ^x- extension convention used elsewhere in the protocol (§4.6). Reference parity: apcore-typescript PR #29.
ephemeral.* namespace + discoverable annotation pilot (apcore RFC docs/spec/rfc-ephemeral-modules.md, #25) — Pilot implementation ahead of upstream RFC acceptance (RFC is in Draft / RFC state). Reserves the ephemeral.* namespace for programmatically-registered modules synthesized at runtime by LLM-agent pipelines (e.g. ToolMaker, ACL 2025, arXiv 2502.11705). Filesystem discovery now refuses to register any ID that falls under ephemeral.* and raises InvalidInputError with code INVALID_MODULE_ID; the namespace is reachable only via Registry.register(). New discoverable: bool = True field on ModuleAnnotations — when False, the module is excluded from Registry.list() (default behaviour; include_hidden=True returns the full set), Registry.iter(), Registry.module_ids, and downstream manifest export, while remaining callable via Registry.get() / Executor.execute(). New Registry.set_event_emitter(emitter) opt-in: when wired, ephemeral.* registrations / unregistrations emit canonical apcore.registry.module_registered / apcore.registry.module_unregistered events whose data payload mirrors the D-35 contextual-audit shape (caller_id defaulting to "@external", plus a redacted identity snapshot when context.identity is set). Without an emitter the same audit information is logged at INFO so it never silently disappears. Registry.register() / Registry.unregister() accept an optional context= keyword used solely to enrich those audit payloads. A soft logging.warning(...) fires when an ephemeral.* module is registered without requires_approval=True (per the RFC). Lifecycle is caller-managed via Registry.unregister(); TTL/GC sweeper and host-side sandboxing are deliberately out of scope for the v1 pilot. New top-level constant EPHEMERAL_NAMESPACE_PREFIX exported from apcore.registry.registry. Pilot disclaimer: the upstream RFC is not yet accepted; downstream SDKs (apcore-typescript, apcore-rust) will follow once Python pilot findings are reported back.
Changed
iter-11 alignment with upstream apcore RFC rfc-ephemeral-modules.md (apcore commit 81df336) — Tightens the ephemeral.* pilot against two new normative rules added during the RFC iter-11 reconciliation round:
Audit-event single-emit rule (RFC §"Audit-event single-emit rule"). The legacy _bridge_registry_events callback in apcore.sys_modules.registration now short-circuits for ephemeral.* module IDs so that exactly oneapcore.registry.module_registered / apcore.registry.module_unregistered event is emitted per registration — the rich registry-side direct emit carrying the full D-35 contextual payload — instead of being followed by a second empty-payload copy from the bridge. Non-ephemeral registrations are unaffected (legacy bridge behaviour preserved for backwards compatibility).
register_internal() rejection (RFC §"register_internal() interaction"). Registry.register_internal() now raises ValueError when called with an ephemeral.* module ID, directing the caller to Registry.register(). Rationale: namespace → registration-mechanism is a 1:1 mapping; mixing the two paths blurs the audit-trail distinction between framework-emitted (system.*) and caller-emitted (ephemeral.*) modules.