chore: ratchet weak public API types - #304
Conversation
Co-authored-by: openhands <[email protected]>
Co-authored-by: openhands <[email protected]>
Endpoint auditContract: pinned release artifact
Actionable client-only calls (0)none Actionable server-only operations (7)
Documented non-divergences (13)Client calls intentionally absent from the filtered contract (11)
Reason: Operational Agent Server endpoints intentionally excluded from the filtered public release artifact.
Reason: Client-ahead API stacked on the pending Agent Server meta-profiles implementation.
Reason: Client-ahead API stacked on the pending Agent Server pre-flight LLM validation endpoint. Server operations covered by an exposed browser URL (2)
Reason: RemoteWorkspace.startWorkspaceSession exposes these authenticated URLs for browser iframe and file requests; they are not HttpClient method calls. |
…ings' into feat/oss-6127-public-type-ratchet
b7dc267 to
dfe83a5
Compare
…type-ratchet Resolve merge conflicts against main: - Adopt main's generated Agent Server schema (1.40.0) and the merged canonical MCP settings operations (endpoint-based create/patch/delete). - Keep the PR's Canonical* type aliases and the public-type ratchet. - Refresh config/public-type-budget.json for the events/types refactor (interface -> type aliases) merged from main. Co-authored-by: openhands <[email protected]>
Co-authored-by: openhands <[email protected]>
|
🤖 OpenHands is reviewing this PR. Head commit: This comment was posted by an AI agent (OpenHands). |
all-hands-bot
left a comment
There was a problem hiding this comment.
This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.
Summary
This PR introduces a repository-wide weak-type ratchet over the built public declaration graph, replaces reachable public any with unknown, and adds runtime narrowing for remote full-state events. I reviewed the diff across all 11 files, the budget config, the checker script, and the remote-state runtime changes.
No material issues found. The change is well-structured and the type tightenings are correct.
Key observations
-
remote-state.tsruntime narrowing is a genuine improvement. The previousObject.assign(this.cachedState, event.value)silently coerced non-object primitives (e.g. a string value would spread its characters as numeric-key properties into the cache). The newisRecordguard throws a descriptive error before any mutation, leaving the cache intact. TheAsyncLock.acquirefinallyblock releases the lock on the throw, and the new test verifies post-throw cache integrity (getExecutionStatusstill resolves). Correct. -
normalizeFullStaterewrite is type-safe. Replacing(info as any).full_statewith a typed intersectionConversationInfo & { full_state?: ConversationInfo }preserves the unwrap behavior without weakening types. Good. -
getWorkspace()return type (ConversationInfo['workspace']=unknown) andmodelDump()(Record<string, unknown>) are correct tightenings fromany. Callers depending on the oldanyergonomics will now get compile-time narrowing requirements, which is the intended ratchet effect. -
Budget tooling is sound. The checker keys sites by
module::semantic-path::kindwith occurrence dedup, fingerprints the containing type node text, excludesdist/generated/, and enforces add/widen/change/remove failures. The self-test covers the four comparison cases plus budget-document validation.check:public-type-budgetbuilds first so it always scans fresh.d.tsoutput. -
Canonical MCP type aliases in
clients.ts/index.tsare pure type-level re-exports with no runtime impact. -
CI/pre-commit integration runs both the self-test and the budget check, matching the documented workflow.
Risk assessment
Low risk. This is a chore/type-safety PR. The only runtime behavioral change (updateStateFromEvent now throws on non-object full-state values instead of silently corrupting the cache) is strictly more defensive and is covered by a regression test. No public API signatures change beyond type tightening, and generated declarations remain governed by the separate OpenAPI drift check.
Why
The client previously had no repository-wide guard against new or widened weak
public types. Important domain boundaries could silently degrade even when
generated Agent Server operations remained strong.
Fixes #300
Linear: OSS-6127
Summary
point and check in a reviewed budget of existing
unknownsites.permanently lowering the budget.
anydeclarations withunknown,with runtime narrowing for remote full-state events.
main(including the Agent Server 1.40.0 schema and the mergedcanonical MCP settings operations from feat: add canonical MCP settings operations #302/feat(events): mirror SDK event payloads #318) and refresh the weak-type
budget for the
events/typesrefactor.Issue Number
#300 / OSS-6127
How to Test
npm run buildnpm run test:public-type-budgetnpm run check:public-type-budgetenv -u AGENT_SERVER_URL npm run test:coverage— 18 suites, 304 testsnpm run check:agent-server-api— checked-in contract is current for 1.40.0npm run test:agent-server-api-toolingnpm run test:endpoint-audit-toolingnpm run lint— 0 errorsnpm run format:check— all files formattedLive evidence refresh (2026-08-08, head
63acaf7= final branch commit after "trigger CI")Re-ran the full validation on the current head (Node v26.6.0):
npm ci-> OK.npm run build->tsc && copy-json-assets && rewrite-relative-importsOK.npm run check:public-type-budget-> Public weak-type budget unchanged: 103 sites (0 any, 103 unknown).npm run test:public-type-budget-> self-test passed.env -u AGENT_SERVER_URL npm run test:coverage-> 18 suites, 304 tests passed (includes theremote-stateandagentchanges).npm run lint-> 0 errors, 8 pre-existing warnings (unchanged).npm run format:check-> all files Prettier-clean.Live evidence (AGENT)
Merge conflict resolution against
mainwas validated locally on commitcbfeeff:The budget refresh mirrors main's
events/typesrefactor (handwritteninterfaces became schema-derived type aliases): six stale
interface:budgettuples were removed and two
type:tuples added at the current fingerprints.Video/Screenshots
Not applicable: this adds public type and CI enforcement without changing the
Canvas UI.
Type
Notes
Depends on #302. Public domain contracts, generic transport internals, and
deliberately opaque Cloud proxy payloads have separate budget groups. Generated
Agent Server declarations remain governed by the SDK OpenAPI quality allowlist
and the pinned generated-file drift check.