waitResource previously asserted result.Data() to map[string]any, which
caused event mode and auto mode to fail with 'data is not an object'
when commands returned strongly-typed DTOs (struct or struct pointer).
Now normalizes via JSON round-trip for non-map types, preserving the
fast path for map[string]any. Added regression tests covering struct
values, struct pointers, nested dotted queries, and error cases.
Terminal success/failure closes kept the acceptance-phase operation state,
emitting self-contradicting envelopes (outcome=success with state=processing).
WithOperationTerminalState now closes the envelope at the observed terminal
status and clears timed_out.
WaitSpec.Validate trimmed status values only for checking and never wrote them
back, so padded declarations passed validation, published a padded Schema, and
then fail-closed at runtime as unknown statuses. NormalizeWaitSpec is now the
single canonical form shared by declaration (corecmd.New / AttachContract),
ToolSpec, and validation: trimmed values, duplicate/conflict rejection,
defensive copy.
Also covers the waitTimeoutDuration secs<=0 branch flagged by the coverage
gate.
int(secs)*time.Second can wrap a pflag-legal MaxInt64 into a non-positive
duration, which skipped the wait deadline and waited forever. Convert with
an overflow check and return a validation error instead.
Only a pending ResultInvoke envelope enters the wait phase, so success,
failure, and partial results are returned unchanged. WaitPoll/WaitEvents
now receive the --wait-timeout deadline (and Command().Context() is bound
to the same loop context) so a blocked poll or subscribe cannot hang past
the declared timeout.
Also allowlist the leftover multi drive_tree_list.py orphan that broke CI
after merging main.
Completes the wait capability per review guidance ("add corresponding
execution hooks and fallback tests for the modes"):
- contract.WaitSpec restores event/auto modes with event_key,
match_field, and a new resource_query (dotted path into the accepted
result data yielding the identifier events correlate against);
per-mode validation of required fields
- internal/wait adds EventStream (leaf-owned transport) and RunEvent:
correlated-event filtering, the same terminal/pending/unknown mapping
as polling, timed-out pending on deadline during consumption, and an
ErrEventStreamEnded sentinel distinguishing stream termination from
fail-closed status errors
- Spec.WaitEvents hook; validateWaitDecl pairs mode with hooks
(poll<->WaitPoll, event<->WaitEvents, auto<->both; surplus hooks
rejected too)
- the wait phase runs event-first in auto mode and falls back to polling
when the stream ends or the subscription fails, under one deadline
spanning both phases; strict event mode surfaces stream errors
- output.CommandResult gains Data() (deep copy) so the framework can
resolve the resource identifier without exposing mutable state
Changed-code coverage re-verified at 100% (CI cross-package recipe).
Addresses the three P1 findings from review 4942891040:
1. event/auto modes were declared but always executed polls. WaitSpec now
accepts poll only (event/auto fail validation with a not-implemented
message); event_key/match_field dead fields removed. Event waiting will
land with its own execution path and mode constant.
2. a deadline reached during the between-poll sleep re-polled with a
cancelled context, so a context-aware poller surfaced its error as a poll
failure instead of the contracted timed-out pending. The wait between
polls now uses a timer + select on ctx.Done(), the deadline is checked
before each poll, and a poll error on a cancelled context closes as
timed-out pending with the last observed status.
3. legacy Invoke/Orchestrate/RunE commands declaring Wait observed a failure
terminal while still exiting 0. validateWaitDecl now requires the
ResultInvoke dispatcher (the only path whose unified envelope can be
closed); the wait phase no longer wraps legacy paths.
Also: dropped the unreachable nonPendingTerminal branch, simplified
waitTimeoutSecs to the flag value (registration always seeds the reviewed
default), and raised changed-code coverage to 100% (new wait-engine edge
tests, output With* unit tests, contractfinal deep-copy coverage,
AttachContract invalid-Wait panic path).
Third-review fix for a CI blocker: run-platform-coverage-gate.sh only
executes ^(TestAllShortcuts|TestCrossPlatformCoverage) yet enforces 100%
coverage of changed production lines, so the TestResolveInputFlags names
left every new input.go statement reported as uncovered. Rename them to
the gate prefix, drop three unreachable pflag Set error branches that no
test could ever cover, and add the reachable stdin read-failure case.
Verified: changed code coverage 100.0000% (67 statements).
Second-review fix: explicitInputFlagName judged usability with an
unconditional TrimSpace while rawValue only trims when Trim is set. For
a non-Trim flag a whitespace main value is usable and shadows a changed
alias; the resolver could then rewrite the shadowed alias (and fail on
its @path) while the fallback chain still read the main value. Mirror
rawValue's usable() exactly and pin the shadow case with a regression
test whose alias path does not exist.
Self-review fixes: a Trim flag receiving " @path" judged usability on the
trimmed value (rawValue) while the source prefix check saw the raw value,
so the token would ship as a literal. Trim before the prefix check. Also
build the file-read error once with a conditional hint option, and pin
the default-value/env passthrough plus Trim edge with regression tests.
Port the lark-cli Flag.Input capability: a KindString flag may declare
Input sources ("file" for @path, "stdin" for -) and the framework
rewrites the explicit token into the payload content before
required/enum/constraint/Validate checks. @@value escapes to a literal
@value; a single stdin consumer per invocation is enforced; a leading
UTF-8 BOM is stripped. Shortcut.Flag gains the same declaration and the
adapter maps it through; LeafSpec inherits it via the LeafFlag alias.
TestLeafArgsOmitsEmptyAndNonPositive called BuildArgs with unset required
CSV flags; after rejecting empty required transforms that path correctly
errors. Satisfy required flags in the omit-empty case and cover the new
RequiredError / scalar-transform branches for the macOS coverage gate.
Co-authored-by: Cursor <cursoragent@cursor.com>
Separator-only inputs like --event-codes ',' passed pre-transform Required
checks, then BuildArgs omitted the key and ConfirmFirst write paths could
still call MCP. Enforce non-empty transform results for Required flags and
add CrossPlatformCoverage regression coverage.
Co-authored-by: Cursor <cursoragent@cursor.com>
Trim Identity.Path and each alias in the declared identity copy (whitespace
could previously reach the wire), and route the declared Selection through
SelectionSpec.Normalized() so leaf and product pass-throughs share one
normalization. Wire output verified unchanged by the catalog gate.
Honor KindBool aliases in BuildArgs/hasEffectiveValue/constraintProvided;
reject MarkRequired+Aliases combinations at registration; validate
env-sourced values against declared enums; drop dead
ValidationEffective/ProjectDeclaredParameters constants and the unused
AnnotateRuntimeFlag parameter; route confirmationBypass through BoolFlag;
refresh retired-flow comments.
Make enum and required-flag validation alias-aware via a shared
flagNameProvided/EffectiveValue path so values passed through flag
aliases are no longer skipped; drop the fully-migrated runtime risk/gate
annotation bridge and the orphaned tool-metadata/title annotation
writers, trimming the cli seam re-exports accordingly.
- schema_cobra_binding: the Identity-vs-spec check is now a defensive
self-consistency assertion (the spec is collected from the same
ContractFinal.Identity), not a cross-source pin; name the real drift
anchors (native annotation cross-check, collector uniqueness
self-validation, homology tool-count tripwire, surface/catalog hash
baselines) and relabel the mismatch diagnostic as collected vs declared.
- schema-compat: state explicitly that accepting interface_type clearing
is a deliberate wire-visible policy decision taken with the MCP pin
retirement (missing = unknown; re-population requires ParamDecl).
- schema_command_registry: drop retired bindings audit / MCP pin from the
peer reviewed-inputs comment; note they must not reappear.
- canonical: schema help no longer claims commands must enter a reviewed
registry; identity is collected from ContractFinal.Identity.
- homology: the tool-count tripwire error now says where to bump it after
review.
- Sweep stale 'reviewed registry' wording in corecmd and the help-flag
completeness gate comment; AGENTS.md interface-facts section matches.
Allow clearing interface_type and expanding constraint group members so
MCP-pin retirement and declare≡execute alias groups stay backward-compatible.
Close platform coverage gaps with TestCrossPlatformCoverage* and bump the
ContractFinal consistency count to 847.
Co-authored-by: Cursor <cursoragent@cursor.com>
Synchronize schemaSourceRootFn via atomic.Value, fail closed on malformed
Int/Bool FlagSpec Default, and stop projecting a sole visible flag as
required when a hidden sibling still satisfies ValidateConstraints.
Co-authored-by: Cursor <cursoragent@cursor.com>
Extract production resetSchemaDeliveryState for RegisterSchemaSourceRoot,
gate production *ForTest call sites, and record the H0 constraint "provided"
semantics in CHANGELOG.
Co-authored-by: Cursor <cursoragent@cursor.com>
Fill the remaining ~12 changed-code stmts blocking Coverage at 99.85%,
and point RFC reviewed-input wording at the Go mapping ledger.
Co-authored-by: Cursor <cursoragent@cursor.com>
Move mapping_exclusions/removals into a reviewed Go ledger so ParamDecl.Property
stays the sole property authority without a committed empty bindings{} Phase 2 gate.
Co-authored-by: Cursor <cursoragent@cursor.com>
Pin admission race shards to timeout_budget (12m/cli 15m), cover
runtimeannotate and schema_source_root success paths for platform/main
gates, and make Windows absolute catalog path checks platform-safe.
Co-authored-by: Cursor <cursoragent@cursor.com>
Runtime assemble was stamping Snapshot.SourceHash with the registry
surface hash, so schema --all catalog_hash diverged from the CI dump
content source_hash and failed Policy. Also remap ContractFinal
Interface.Ref onto pinned MCP metadata so interface_type stays aligned.
Co-authored-by: Cursor <cursoragent@cursor.com>
Move schema authority to declare-time ParamDecl/ContractFinal and
ResolveSchemaBuild so CI/runtime assemble instead of shipping JSON
exclusions/meta-index as delivery sources.
Co-authored-by: Cursor <cursoragent@cursor.com>
Break the remaining corecmd→cli reverse dependency by owning
runtimeannotate and contractfinal on the framework side, with cli
keeping thin re-exports. Document the three authoring tiers and that
Shortcut may use DeclareLeafMetadata.
Co-authored-by: Cursor <cursoragent@cursor.com>