Skip to content

fix(sdk): preserve contract errors through safe() and isDefinedError - #1671

Draft
rickylabs wants to merge 8 commits into
mainfrom
fix/sdk-typed-error-channel
Draft

fix(sdk): preserve contract errors through safe() and isDefinedError#1671
rickylabs wants to merge 8 commits into
mainfrom
fix/sdk-typed-error-channel

Conversation

@rickylabs

@rickylabs rickylabs commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Summary

Plans the #1350 repair so contract-defined oRPC errors retain literal code and schema-derived data from baseContract, through ServiceClient, into safe() and isDefinedError().

This PR still contains research and harness plan artifacts only. The coordinator amendment authorizes the real client loss point as the sixth path, assigns all metadata vocabulary to #1466, and leaves implementation blocked on fresh Tier-A review followed by a separate-session PLAN-EVAL PASS.

Scope

  • Archetype / area: Archetype 1 small-contract slice with docs overlay; packages/contracts + packages/sdk
  • Closes [sdk-client S1] fix(sdk): preserve contract errors through safe() and isDefinedError #1350
  • Run dir: .llm/runs/fix-sdk-typed-error-channel--0.0.7-wave1/
  • Exact six-path product/test/docs ceiling:
    1. packages/contracts/src/application/contract-primitives.ts
    2. packages/sdk/src/client/errors.ts
    3. packages/sdk/src/ports/service-client.ts
    4. packages/sdk/tests/readme-doctest_test.ts
    5. docs/site/services-sdk/sdk.md
    6. docs/site/services-sdk/how-to/discover-services.md
  • Any seventh product, test, or docs path requires a fresh coordinator ruling.
  • Explicitly excluded: packages/contracts/src/public/mod.ts, all metadata definition/export work, packages/contracts/README.md, and benchmark reference prose.

Decided error contract

type SafeResult<TOutput, TError = ThrowableError> =
  | SafeSuccess<TOutput>
  | SafeFailure<TError>;

type SafeFailure<TError> =
  | ([Exclude<TError, DefinedErrorLike>, undefined, false, false] & {
      error: Exclude<TError, DefinedErrorLike>;
      data: undefined;
      isDefined: false;
      isSuccess: false;
    })
  | ([NarrowDefined<TError>, undefined, true, false] & {
      error: NarrowDefined<TError>;
      data: undefined;
      isDefined: true;
      isSuccess: false;
    });

function safe<TOutput, TError = ThrowableError>(
  promise: ClientPromiseResult<TOutput, TError>,
): Promise<SafeResult<TOutput, TError>>;

function isDefinedError<T>(error: T): error is NarrowDefined<T>;

The contract builder uses an explicit four-generic ContractBuilder. Its error map is derived from typeof commonErrorMap, never open ErrorMap, preserving all six declared codes and their schema-derived data. Its fourth generic remains exactly Record<never, never>.

The acceptance fixture proves the existing ~orpc.meta slot is Record<never, never> and not any/unknown. It defines no metadata fields, initializes no metadata, exports no metadata type, and makes no claim that #1466's later semantic fixture is proven.

No new SDK or contracts export name is introduced; internal narrowing helpers remain off every barrel.

Breaking-change statement

Breaking published contract; not patch-level. The current public SafeFailure has one arm with isDefined: boolean and failure data: null. The accepted/upstream-compatible contract has two literal-discriminated arms and failure data: undefined. Tightening the base error map also intentionally rejects undeclared codes. Repository consumers were searched; external JSR consumers may need to update assertions or constructed SafeFailure values.

Acceptance proof

The real-export fixture must first reproduce the base RED:

TS2339: Property 'code' does not exist on type 'never'.

After implementation, the same fixture must prove:

  • the exact six literals NOT_FOUND | VALIDATION_ERROR | UNAUTHORIZED | FORBIDDEN | RATE_LIMITED | SERVICE_UNAVAILABLE survive through the real ServiceClient promise, safe(), and isDefinedError();
  • error.data remains schema-specific by code;
  • NOT_DECLARED is rejected;
  • a plain Error remains in the isDefined: false arm;
  • the fourth builder metadata slot is exactly Record<never, never> and not any/unknown, without inventing metadata vocabulary.

Slices

  • P0 research + concrete plan + design checkpoint — c7a6f3d32
  • P0a coordinator scope/ownership amendment — 2fa2f71dc
  • S1 record the real-export RED, preserve six exact builder errors, and retain the empty fourth generic
  • S2 carry the six-literal error channel through the client promise and safe helpers
  • S3 rewrite every enumerated error-story location on both authorized docs pages
  • S4 run and record the complete proving gate set
  • Fresh Tier-A review of the amended head
  • Separate-session PLAN-EVAL PASS before S1
  • Separate-session IMPL-EVAL PASS before merge

Validation

  • deno doc --filter safe|isDefinedError|SafeResult packages/sdk/src/client/mod.ts — confirmed the current published erasure
  • deno doc --filter baseContract packages/contracts/mod.ts — confirmed ReturnType<typeof oc.errors>
  • deno eval --check --unstable-kv ... — expected base RED reproduced: TS2339, error.code does not exist on never
  • Whole-repo executed rg consumer searches — mapped SDK, Fresh, CRUD, query/desktop, CLI/template, docs, and surface-baseline consumers
  • Current raw SDK publish dry-run — exit 0, no actual slow-type diagnostic
  • Current raw contracts publish dry-run with sanctioned oRPC allowance — exit 0
  • Current JSR audit — known SDK F-DOCT-5 remains red; not claimed as a leaf regression or green result
  • Plan amendment formatting and diff checks — pass
  • Implementation gates — not run; prohibited before PLAN-EVAL

Harness

  • Run dir: .llm/runs/fix-sdk-typed-error-channel--0.0.7-wave1/
  • Phase: plan
  • Fresh Tier-A reviews amended head 2fa2f71dc; only then may a separate PLAN-EVAL run.
  • No implementation may begin before PLAN-EVAL PASS.
  • Do not merge until the selected Plan-Gate and mandatory final IMPL-EVAL pass are complete.

Drift / Debt

  • Resolved: packages/sdk/src/ports/service-client.ts is the authorized sixth path.
  • Resolved: [sdk-client S2] feat(sdk): define NetScriptProcedureMeta without erasing contract errors #1466 owns metadata definition, initialization, export, and semantic proof.
  • Denied: contracts public-barrel and metadata-export expansion.
  • Deferred follow-up debt: contracts/benchmark prose outside the two authorized docs pages describes the current erasure; it remains outside this leaf.
  • New architecture debt accepted: none.

Definition of Done

  • Coordinator ruling is incorporated as the exact six-path ceiling with no metadata-export branch.
  • Fresh Tier-A review passes on the amended head.
  • Separate-session PLAN-EVAL passes before product implementation.
  • The real-export RED is recorded at base and turns green only through exact end-to-end inference.
  • The empty fourth metadata generic is proven without defining [sdk-client S2] feat(sdk): define NetScriptProcedureMeta without erasing contract errors #1466 vocabulary.
  • Both published docs pages are coherent at every enumerated error-story location.
  • Check, test, publish dry-run, docs-source-format, docs-accuracy, quality scan, architecture check, and JSR evidence are recorded honestly.
  • Base-red surface:diff, JSR F-DOCT-5, pinned doc-lint baselines, and test(queue): eliminate typed-queue DLQ timing flake #1667 are not laundered as green.
  • Separate-session IMPL-EVAL passes before ready-for-review/merge.

@rickylabs rickylabs added this to the 0.0.7 milestone Aug 15, 2026 — with ChatGPT Codex Connector

Copy link
Copy Markdown
Owner Author

[PHASE: PLAN]

Research and the concrete plan are committed in .llm/runs/fix-sdk-typed-error-channel--0.0.7-wave1/. No product implementation has begun.

Findings

  1. The public error map is first widened in baseContract, but the decisive client-side loss is ServiceClientMethod returning plain Promise<TOutput> in packages/sdk/src/ports/service-client.ts. That file is outside the declared surface, so implementation cannot correctly proceed without a scope ruling.
  2. The brief assigns procedure-metadata preservation to [sdk-client S1] fix(sdk): preserve contract errors through safe() and isDefinedError #1350, while live [sdk-client S2] feat(sdk): define NetScriptProcedureMeta without erasing contract errors #1466 and the existing maintainer comment on [sdk-client S1] fix(sdk): preserve contract errors through safe() and isDefinedError #1350 assign it to [sdk-client S2] feat(sdk): define NetScriptProcedureMeta without erasing contract errors #1466. The plan leaves metadata conditional on an ownership ruling.
  3. The planned contract preserves the procedure's exact error union through ClientPromiseResult<TOutput, TError>; safe() returns literal defined/undefined failure arms and isDefinedError() narrows to the defined-error extract. This is a breaking published-contract correction, not patch-level.
  4. The base RED is reproduced: after safe(service.method(...)), the defined branch reports TS2339 because error.code is never.

Next

  • Topic orchestrator rules on the required file expansion, metadata ownership/export scope, and stale out-of-scope published prose.
  • A separate session performs PLAN-EVAL.
  • Implementation remains prohibited until PLAN-EVAL passes.

rickylabs added a commit that referenced this pull request Aug 15, 2026
…error

Author stopped on three real scope items at c7a6f3d (PR #1671).
Dispatched the ruling: approve service-client.ts as the sixth path, deny
public/mod.ts and any NetScriptProcedureMeta definition/export, treat the
stale contracts README/benchmark prose as a seventh-path rescope.

Records in drift.md that my brief mis-stated #1350/#1466 metadata
ownership by quoting an umbrella checkbox instead of that body's
normative header, #1350's owner comment 5227724542, and the live #1466
child. The author caught it; uncaught it would have duplicated #1466.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pCd2QWkCscgZpVdjcUPST

Copy link
Copy Markdown
Owner Author

[PHASE: PLAN]

Plan amendment receipt for coordinator ruling; implementation remains untouched.

Receipt

  • Amended head: 2fa2f71dc5b498c16221461439e53b9f5dc1d5d5
  • Commit: docs(harness): lock typed error scope ruling
  • Artifact-only diff: research.md, plan.md, context-pack.md, worklog.md, drift.md, and supervisor.md under the existing run directory
  • Push: explicit git push origin HEAD:refs/heads/fix/sdk-typed-error-channel
  • PR posture: draft; sole lifecycle label status:plan; milestone 0.0.7

Exact six-path ceiling

  1. packages/contracts/src/application/contract-primitives.ts
  2. packages/sdk/src/client/errors.ts
  3. packages/sdk/src/ports/service-client.ts
  4. packages/sdk/tests/readme-doctest_test.ts
  5. docs/site/services-sdk/sdk.md
  6. docs/site/services-sdk/how-to/discover-services.md

Any seventh product, test, or docs path is a rescope requiring a fresh coordinator ruling. The contracts public barrel, contracts README, and benchmark reference prose are not authorized.

Locked ownership and proof

Next

  • Fresh Tier-A reviews this amended head.
  • Only after that review passes may a separate PLAN-EVAL run.
  • No implementation before PLAN-EVAL PASS.

rickylabs added a commit that referenced this pull request Aug 15, 2026
Measured only after the author was fully idle 132s. Amendment is exactly
six run-artifact paths, zero others, plan-only against base. Six-path
ceiling with seventh declared a rescope; public/mod.ts conditional
genuinely removed rather than annotated; acceptance revised to six
literals plus Record<never, never> meta-slot non-erasure with no
dependency on NetScriptProcedureMeta; breaking published-contract
disclosure retained at full strength.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pCd2QWkCscgZpVdjcUPST
Separate-session Fable 5 medium evaluation of PR #1671 plan head 2fa2f71.
Verdict PASS with five non-blocking advisories.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RuDy1h3UiCkLzo1PLk5Sc
@rickylabs

Copy link
Copy Markdown
Owner Author

PLAN-EVAL — PASS

Field Value
Evaluator Claude · claude-fable-5 · medium · Remote Control (formal_plan_evaluation, route matched) — session 50898ac7-6e79-4f31-ae18-694bb36b7c79, separate from plan author 01a006f3…
Evaluated head 2fa2f71dc5b498c16221461439e53b9f5dc1d5d5 (base 0ef48c2ec)
Artifact .llm/runs/fix-sdk-typed-error-channel--0.0.7-wave1/plan-eval.md @ f76a3c45b

Findings (all re-derived; executed evidence in the artifact)

Advisories (non-blocking)

  1. A1 Record the RED as both TS18046 (unknown, plan snippet) and TS2339 (never, isDefinedError).
  2. A2 packages/sdk has no zod mapping (probe → TS2307). Build the fixture route from @netscript/contracts-exported schemas; a zod entry in packages/sdk/deno.json would be a seventh path.
  3. A3 Locked type SafeFailure<TError> drops today's default — keep = ThrowableError or declare the extra break.
  4. A4 "Tracked debt" for bench prose has no arch-debt.md entry; add one in slice 4. Research §3 overstates packages/contracts/README.md (it does not describe erasure).
  5. A5 Close gate: [sdk-client S1] fix(sdk): preserve contract errors through safe() and isDefinedError #1350 acceptance boxes still mention metadata; state the split under comment 5227724542, do not tick metadata boxes.

Implementation may begin at the plan head. No product/test/docs files were modified by this evaluation.

rickylabs added a commit that referenced this pull request Aug 15, 2026
PASS at evaluated head 2fa2f71; artifact-only commit f76a3c4
verified. S1 released to the same author for plan slice 1 only
(contract-primitives.ts + readme-doctest_test.ts), with slices 2-4
fenced off including service-client.ts.

Carries A1 (both TS18046 and TS2339 REDs, not just TS2339), A2 (exported
contracts schemas, no SDK zod mapping), A3 (retain SafeFailure default),
A4 (no arch-debt.md or new file; supervisor files any dedup issue), A5
(tick no metadata boxes).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pCd2QWkCscgZpVdjcUPST

Copy link
Copy Markdown
Owner Author

[PHASE: IMPL] — S1 receipt

Slice 1 is committed and pushed at dc034d680b53c2845e9b82f73c6c709f2c51e2b3. This session stops here for fresh Tier-A review; slice 2 has not started.

Scope observed

Changed product/test paths:

  1. packages/contracts/src/application/contract-primitives.ts
  2. packages/sdk/tests/readme-doctest_test.ts

The only other changed paths are the five pre-existing run artifacts (context-pack.md, drift.md, plan.md, research.md, and worklog.md). No new artifact file was created. No slice 2–4 path, lock file, #1348, or #1466 was touched.

Required RED — captured once before implementation

The fixture uses real package exports from @netscript/contracts and the SDK root; it contains no SDK-side zod mapping.

{
  "exitCode": 1,
  "command": "deno check --unstable-kv <files>",
  "selection": { "filesSelected": 1, "batches": 1, "failedBatches": 1 },
  "summary": {
    "totalOccurrences": 2,
    "uniqueOccurrences": 2,
    "uniqueCodes": 2,
    "uniquePaths": 1
  },
  "groups": [
    {
      "code": "TS18046",
      "message": "'discriminated.error' is of type 'unknown'.",
      "count": 1,
      "location": "packages/sdk/tests/readme-doctest_test.ts:21:5"
    },
    {
      "code": "TS2339",
      "message": "Property 'code' does not exist on type 'never'.",
      "count": 1,
      "location": "packages/sdk/tests/readme-doctest_test.ts:26:19"
    }
  ]
}

The RED was not rerun seeking a tidier failure.

S1 contract

The base builder is now explicitly four-generic:

ContractBuilder<
  Schema<unknown, unknown>,
  Schema<unknown, unknown>,
  BaseContractErrors,
  Record<never, never>
>

BaseContractErrors is derived from the exact private common-error map, preserving the six literal keys NOT_FOUND | VALIDATION_ERROR | UNAUTHORIZED | FORBIDDEN | RATE_LIMITED | SERVICE_UNAVAILABLE and their schema-specific data. The fixture rejects NOT_DECLARED.

The fourth slot remains exactly Record<never, never> and the fixture proves it is neither any nor unknown. No metadata type, field vocabulary, initializer, dependency, or export was introduced, and no metadata acceptance box was ticked. packages/sdk/src/client/errors.ts remains untouched; its planned SafeFailure<TError = ThrowableError> repair belongs to S2.

Structured gate verdicts

Final focused check:

{
  "exitCode": 0,
  "command": "deno check --unstable-kv <files>",
  "selection": { "filesSelected": 4, "batches": 1, "failedBatches": 0 },
  "summary": {
    "totalOccurrences": 0,
    "uniqueOccurrences": 0,
    "uniqueCodes": 0,
    "uniquePaths": 0
  },
  "groups": []
}

The four checked files were the two S1 files plus the affected CRUD and workers type consumers. Two implementation iterations were also recorded honestly in worklog.md: TS9010 + TS9027 (resolved with the exact private annotation), then TS2322 (resolved by removing contextual widening).

Focused tests:

{
  "exitCode": 0,
  "command": [
    "deno",
    "test",
    "--reporter=tap",
    "--allow-all",
    "packages/sdk/tests/readme-doctest_test.ts",
    "plugins/workers/services/src/routers/health-soundness_test.ts"
  ],
  "summary": {
    "passed": 3,
    "failed": 0,
    "ignored": 0,
    "totalResults": 3,
    "uniqueFailures": 0
  },
  "failures": []
}

Focused lint:

{
  "exitCode": 0,
  "selection": { "filesSelected": 2, "batches": 1 },
  "summary": {
    "totalOccurrences": 0,
    "uniqueOccurrences": 0,
    "uniqueRules": 0,
    "uniquePaths": 0
  },
  "groups": []
}

Focused format write:

{
  "exitCode": 0,
  "command": "deno fmt",
  "mode": "write",
  "summary": {
    "filesSelected": 2,
    "batches": 1,
    "failedBatches": 0,
    "findings": 0,
    "ignoredFindings": 0
  },
  "findings": []
}

Final format check:

{
  "exitCode": 0,
  "command": "deno fmt --check",
  "mode": "check",
  "summary": {
    "filesSelected": 2,
    "batches": 1,
    "failedBatches": 0,
    "findings": 0,
    "ignoredFindings": 0
  },
  "findings": []
}

Root/final-slice gates were not run, as required. typed-queue_test.ts was not selected, so #1667 was not encountered. The known surface:diff, JSR F-DOCT-5, and pinned raw doc-lint reds are not claimed green or attributed to this slice.

Push and PR posture

  • Explicit refspec used: git push origin HEAD:refs/heads/fix/sdk-typed-error-channel
  • Local HEAD and remote branch both resolve to dc034d680b53c2845e9b82f73c6c709f2c51e2b3
  • Worktree is clean
  • PR remains open and draft
  • Labels remain type:fix, area:sdk, priority:p1, and sole status label status:plan
  • No acceptance checkbox, ready flip, relabel, evaluator launch, or review arrangement was performed

STOP: waiting for a fresh Tier-A review before any authorization for S2.

rickylabs added a commit that referenced this pull request Aug 15, 2026
Scope exact: two authorized files plus five existing artifacts, no
seventh path, no new file, slice-2 files untouched. A1 satisfied
precisely - TS18046 and TS2339 captured together in one structured run
and not rerun. No NetScriptProcedureMeta anywhere in contracts/sdk src;
fourth generic preserved as Record<never, never>.

Gates: check 105 files 0 occurrences, doctest 2/0, contracts+sdk 77/0.

Flags a non-blocking A5 observation: three process boxes with commit
evidence are ticked, none claiming metadata acceptance. My brief was
stricter than the ruling, so this is my over-hardening, not an author
violation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pCd2QWkCscgZpVdjcUPST

Copy link
Copy Markdown
Owner Author

[PHASE: IMPL] — S2 receipt

Slice 2 is committed and pushed at ca7ade409be0cc0c064e75f5bfa1bd109e06d013. This session stops here for fresh Tier-A review; slice 3 and all docs work remain unstarted.

Scope observed

Changed S2 product/test paths:

  1. packages/sdk/src/client/errors.ts
  2. packages/sdk/src/ports/service-client.ts
  3. packages/sdk/tests/readme-doctest_test.ts

The only other changes are the existing context-pack.md and worklog.md run artifacts. No new file, seventh path, docs page, lock file, metadata vocabulary, #1348/#1466 mutation, or acceptance-box edit was introduced. The recorded S1 TS18046/TS2339 evidence is byte-identical to dc034d680 and was not rerun.

Error-channel contract

  • ServiceClientMethod<TInput, TOutput, TError = ThrowableError> returns upstream public ClientPromiseResult<TOutput, TError>.
  • A private conditional derives TError with upstream public ErrorFromErrorMap<TErrorMap> from the real procedure ~orpc.errorMap.
  • Existing two-generic ServiceClientMethod<TInput,TOutput> consumers remain valid through the defaulted third parameter.
  • SafeFailure<TError = ThrowableError> retains that exact default and now has literal non-defined/defined arms with failure data undefined.
  • safe<TOutput,TError = ThrowableError> consumes the real promise error marker.
  • isDefinedError<T> extracts the upstream-shaped defined members, intersects the runtime-proven defined: true, and preserves each member's literal code/data.
  • No upstream type is re-exported and no local zod map or ambient declaration was added.

The two former suppressions

Both S2-specific @ts-expect-error comments were removed; no @ts-ignore, as any, as unknown as, or widened substitute exists.

The former safe-path marker became this exact positive assertion:

type _SafePreservesExactErrorCode = Assert<
  Equal<typeof discriminated.error.code, ExpectedBaseErrorCode>
>;
const preservedCode: ExpectedBaseErrorCode = discriminated.error.code;

The same branch positively proves code-specific NOT_FOUND and VALIDATION_ERROR data using the exported contracts schemas.

The former guard-path marker became:

type _GuardNarrowsToExactDefinedError = Assert<
  Equal<typeof guarded.error.code, ExpectedBaseErrorCode>
>;
const definedError: DefinedError<ExpectedBaseErrorCode> = guarded.error;

That guarded branch also proves NOT_FOUND retains ContractSchemaOutput<typeof NotFoundErrorSchema>. Separate assertions prove SafeFailure<Error> keeps Error only in the isDefined: false arm and yields never in the defined arm.

Structured verdicts

Final focused check, including 15 SDK/Fresh source, runtime-test, and type-fixture consumers:

{
  "exitCode": 0,
  "command": "deno check --unstable-kv <files>",
  "selection": { "filesSelected": 15, "batches": 1, "failedBatches": 0 },
  "summary": {
    "totalOccurrences": 0,
    "uniqueOccurrences": 0,
    "uniqueCodes": 0,
    "uniquePaths": 0
  },
  "groups": []
}

Final focused and consumer tests:

{
  "exitCode": 0,
  "command": [
    "deno",
    "test",
    "--reporter=tap",
    "--allow-all",
    "packages/sdk/tests/readme-doctest_test.ts",
    "packages/sdk/tests/query/query-factory_test.ts",
    "packages/sdk/tests/desktop/desktop-rpc-client_test.ts",
    "packages/fresh/src/diagnostics/error/extract_test.ts"
  ],
  "summary": {
    "passed": 12,
    "failed": 0,
    "ignored": 0,
    "totalResults": 12,
    "uniqueFailures": 0
  },
  "failures": []
}

The doctest-only run independently passed 3/3, including the new runtime test that verifies defined-error identity, plain-error rejection, both literal discriminants, and all four tuple positions.

The first lint run was honestly red:

{
  "exitCode": 1,
  "selection": { "filesSelected": 3, "batches": 1 },
  "summary": {
    "totalOccurrences": 2,
    "uniqueOccurrences": 2,
    "uniqueRules": 1,
    "uniquePaths": 1
  },
  "groups": [{
    "rule": "verbatim-module-syntax",
    "message": "Import identifier only used in types",
    "count": 2,
    "path": "packages/sdk/tests/readme-doctest_test.ts",
    "locations": ["4:3", "6:3"]
  }]
}

Both schema imports were marked type-only. Final lint:

{
  "exitCode": 0,
  "selection": { "filesSelected": 3, "batches": 1 },
  "summary": {
    "totalOccurrences": 0,
    "uniqueOccurrences": 0,
    "uniqueRules": 0,
    "uniquePaths": 0
  },
  "groups": []
}

Final format write:

{
  "exitCode": 0,
  "command": "deno fmt",
  "mode": "write",
  "summary": {
    "filesSelected": 3,
    "batches": 1,
    "failedBatches": 0,
    "findings": 0,
    "ignoredFindings": 0
  },
  "findings": []
}

Final format check:

{
  "exitCode": 0,
  "command": "deno fmt --check",
  "mode": "check",
  "summary": {
    "filesSelected": 3,
    "batches": 1,
    "failedBatches": 0,
    "findings": 0,
    "ignoredFindings": 0
  },
  "findings": []
}

Additional implementation checks were also green: initial three-file check, post-assertion one-file check, and the repeated final 15-file consumer check. The broader 12-test consumer run was repeated after final formatting and remained 12/12.

Consumer compatibility evidence

The 15-file check covered:

  • the defaulted ServiceClientMethod consumer in service-query utils;
  • SDK client factory and desktop client;
  • service-query-utils, SDK assignability, define-services, desktop, and accepted-RFC type fixtures;
  • query-factory and desktop runtime tests;
  • Fresh's published SDK isDefinedError consumer and its tests.

Runtime tests covered SDK doctest/error tuples, query factories, desktop client behavior, and Fresh error extraction. Live service integration suites were not run because this slice forbids a runtime lease.

Push and PR posture

  • Explicit push: git push origin HEAD:refs/heads/fix/sdk-typed-error-channel
  • Local HEAD and remote branch: ca7ade409be0cc0c064e75f5bfa1bd109e06d013
  • Worktree: clean
  • PR: open and draft
  • Labels: type:fix, area:sdk, priority:p1, and sole status status:plan
  • No ready flip, relabel, checkbox tick, evaluator launch, or review arrangement

Root/final-slice gates were not run. typed-queue_test.ts was not selected, so #1667 was not encountered. Known surface:diff, JSR F-DOCT-5, and raw doc-lint baseline reds are not claimed green or attributed to S2.

STOP: waiting for a fresh Tier-A review before any slice 3 authorization.

rickylabs added a commit that referenced this pull request Aug 15, 2026
Both @ts-expect-error markers became positive Assert<Equal<...>>
assertions with no suppression added; the author additionally closed a
vacuity hole by asserting IsAny<BaseMeta> is false alongside the
Record<never, never> equality.

SafeFailure default retained at errors.ts:71; no zod map or ambient
redeclaration; NetScriptProcedureMeta still absent; no extra boxes.
Worklog's 16 deletions verified as a table reflow with the S1 RED row
surviving verbatim.

Gates: check 105 files 0 occurrences, doctest 3/0, sdk+contracts 78/0,
lint 0, fmt 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pCd2QWkCscgZpVdjcUPST
@rickylabs

rickylabs commented Aug 15, 2026

Copy link
Copy Markdown
Owner Author

[PHASE: IMPL] — S3 receipt

Slice 3 is committed and pushed at c7cba6d9bd6aef1fbeb0e8e9778a5d979c8544bd. This session stops here for fresh Tier-A review; S4 has not started.

Scope observed

Changed exactly the two S3 docs paths plus the existing run worklog:

  1. docs/site/services-sdk/sdk.md
  2. docs/site/services-sdk/how-to/discover-services.md
  3. .llm/runs/fix-sdk-typed-error-channel--0.0.7-wave1/worklog.md

The four landed product/test files and deno.lock remain byte-identical to ca7ade409. No new file, seventh path, product/test edit, metadata vocabulary or acceptance claim, issue mutation, label change, or checkbox tick was introduced.

Disposition-table receipt

Planned row Disposition
sdk.md:12-20 Retained at final 12-22, scoped to input/output/declared-error non-drift; transport and arbitrary throws are non-defined failures.
sdk.md:31-38 Retained/corrected at 33-41: L1 infers input, output, and the declared-error union.
sdk.md:58-70 Retained/corrected at 61-71: baseContract error schemas flow through the client promise and safe(); runtime failures stay outside the contract.
sdk.md:113-114 Retained/corrected at 118-120: direct calls infer declared errors but reject; the comment points readers to safe().
sdk.md:196-198 Replaced at 203-249: all six codes, literal isSuccess/isDefined, non-defined termination, code-selected data, and the scoped predicate story.
discover-services.md:9-14 Retained at final 11-15, scoped to input/output/declared errors with discovery/transport failures non-defined.
discover-services.md:96-101,114-115 Retained/corrected at 99-118: baseContract carries the six errors and the call comment includes declared-error inference.
discover-services.md:135-154 Replaced at 137-176: all six codes, literal discriminants, every failure terminated, and NOT_FOUND schema data.
discover-services.md:205-229 Replaced at 227-264: success-only return, non-defined throw, and VALIDATION_ERROR schema data before the defined failure is thrown.

Both pages name exactly NOT_FOUND | VALIDATION_ERROR | UNAUTHORIZED | FORBIDDEN | RATE_LIMITED | SERVICE_UNAVAILABLE. In each copyable safe example, success returns only under result.isSuccess; !result.isDefined throws; declared failures are then handled and thrown. data is described and demonstrated as selected by error.code from its contract schema, never as an open bag or any.

Compile evidence

The new SDK error fence compiles directly against real workspace entrypoints:

{
  "gate": "docs:snippets",
  "outcome": "PASS",
  "exitCode": 0,
  "census": { "scanned": 581, "tsLike": 298, "tier1": 36, "checked": 22, "exempt": 14, "outsideFloor": 262, "malformed": 0 }
}

Discover-services is outside the current snippet day-one floor, so its changed examples were compiled page-isolated in two batches. The only supplied prelude replaced the project-local contract import with a real baseContract route having the same list input/output shape; all documented client construction, branching, exact-code annotations, and code-specific data accesses remained unchanged:

{
  "gate": "discover-services-error-examples",
  "verdict": "PASS",
  "results": [
    { "source": [105, 146], "code": 0, "rootLockUnchanged": true, "temporaryLockRewritten": true },
    { "source": [232], "code": 0, "rootLockUnchanged": true, "temporaryLockRewritten": true }
  ]
}

The existing SDK doctest remained green:

{
  "schemaVersion": 1,
  "exitCode": 0,
  "summary": { "passed": 3, "failed": 0, "ignored": 0, "totalResults": 3 },
  "failures": []
}

Gate verdicts

{
  "docsSourceFormat": { "outcome": "PASS", "exitCode": 0, "durationMs": 444, "summary": "Docs source format: OK" },
  "docsAccuracy": { "outcome": "PASS", "exitCode": 0, "durationMs": 11532, "publishedSourcePages": 199 },
  "docsSourceLinks": { "outcome": "PASS", "exitCode": 0, "docs": 103, "brokenLinks": 0, "brokenAnchors": 0, "orphans": 0 },
  "siteVerify": { "outcome": "PASS", "exitCode": 0, "covers": ["source-format", "build", "rendered-output", "rendered-links", "caveats"] },
  "scope": { "outcome": "PASS", "productAndTestFilesByteIdentical": true, "denoLockUnchanged": true, "newFiles": 0 }
}

The docs-accuracy PASS is claimed only for invariants that script implements; it is not used as proof of the page-level error narrative. The known raw-red surface:diff, JSR F-DOCT-5, and pinned raw doc-lint baselines were not run in S3 and remain known red. typed-queue_test.ts was not selected, so #1667 was not encountered. Root/final gates remain reserved for S4.

Push and PR posture

  • Explicit push: git push origin HEAD:refs/heads/fix/sdk-typed-error-channel
  • Local and remote head: c7cba6d9bd6aef1fbeb0e8e9778a5d979c8544bd
  • Worktree: clean
  • PR: open and draft
  • Labels: type:fix, area:sdk, priority:p1, sole status status:plan
  • No ready flip, relabel, acceptance tick, evaluator launch, or review arrangement

STOP: waiting for fresh Tier-A review before any S4 authorization.

Lock-hygiene guardrail (post-commit attestation)

The guardrail arrived after S3 had been committed and this receipt posted. The exact requested comparison was nevertheless run against pushed head c7cba6d9bd6aef1fbeb0e8e9778a5d979c8544bd:

git diff --quiet ca7ade409be0cc0c064e75f5bfa1bd109e06d013 -- deno.lock && echo LOCK-IDENTICAL || echo LOCK-DRIFTED
LOCK-IDENTICAL

Working-copy deno.lock, ca7ade409:deno.lock, and HEAD:deno.lock all have SHA-256 edfa0c24b70e0d830acce68aad6f5da42b66a88527aef4b80f3f82d989d1820c; zod@4.1.12 occurs zero times in both the working and committed lock. During pre-commit exploratory compilation, an explicit npm:zod@4.1.12 probe had temporarily added two lock entries; those exact hunks were inspected and removed before the S3 commit without deleting or regenerating the lock. The committed slice and remote head never contained the drift. No new commit was created for this post-commit attestation.

rickylabs added a commit that referenced this pull request Aug 15, 2026
Scope exact: two docs pages plus one existing artifact, packages/
untouched. Lock verified LOCK-IDENTICAL to ca7ade4.

All six authoritative literals (NOT_FOUND, VALIDATION_ERROR,
UNAUTHORIZED, FORBIDDEN, RATE_LIMITED, SERVICE_UNAVAILABLE) appear on
both pages; a guessed set had shown a false 5-of-6 gap, so the set was
derived from source before filing anything. Literal isSuccess/isDefined
branching present on both; no NetScriptProcedureMeta, no metadata claim.

Gates: docs-source-format PASS, docs-accuracy PASS, doctest 3/0.

Records that the reported deno.lock zod drift was not reproducible, so
the guardrail was dispatched as preventive rather than corrective.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pCd2QWkCscgZpVdjcUPST
@rickylabs

rickylabs commented Aug 15, 2026

Copy link
Copy Markdown
Owner Author

@/home/codex/.claude/jobs/944115a6/tmp/s4r-comment-body.md

rickylabs added a commit that referenced this pull request Aug 15, 2026
S4 conduct is correct: run-artifact-only (0 non-run-artifact paths),
LOCK-IDENTICAL, receipts bound gitHead == actualGitHead with no waiver,
unreached gates recorded NOT_RUN rather than omitted, and the author
stopped instead of editing S1/S2 source to green its own gate.

Blocker verified independently: SDK raw doc-lint is 3 at base 0ef48c2
and 13 at head. Ten new private-type-ref diagnostics on ServiceClientMethod,
ServiceClientShape, SafeFailure, SafeResult, isDefinedError and safe -
a genuine leaf-owned published-surface regression, correctly not laundered
into the known F-DOCT-5 baseline.

Needs a coordinator ruling for a bounded source-touching S5. IMPL-EVAL
not requested at this head.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pCd2QWkCscgZpVdjcUPST
rickylabs added a commit that referenced this pull request Aug 15, 2026
codex-resume delivers to thread 01a006f3 (rollout grep 2->4, mtime +143s)
but the backend refuses: usage limit hit, retry at 2026-08-20 05:31,
1,576,949 tokens used. Leaf unchanged at db8aadd, clean, lock identical.

Records the discipline gap this exposed: rollout-grep proves a message
was written, not that a model could act on it. Delivery proof and
liveness proof are separate checks; never arm a head-change watcher on
an unproven-live author.

No retries, no supervisor substitution as implementer. Coordinator
decision required: credits, wait for reset, or lane escalation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pCd2QWkCscgZpVdjcUPST
rickylabs added a commit that referenced this pull request Aug 15, 2026
One-shot test as directed: fresh gpt-5.6-sol/medium session, new thread
01a00767, dedicated detached worktree at db8aadd, leaf sender
preserved. Identical refusal - usageLimitExceeded, willRetry false,
hasCredits false, balance 0, limitId premium, turn failed in 2147ms.
Quota is account-wide, not thread-local.

Parked: temp worktree and scratch branch removed, s4r never pushed, leaf
clean at db8aadd == remote == PR, lock identical, draft status:plan.
No retries, no substitute authorship.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pCd2QWkCscgZpVdjcUPST
…correction map

Maps all 13 new leaf-owned deno-doc-lint private-type-ref findings from S4
(contracts 3, SDK 10) to individual type-safe corrections, verified against
isolated deno doc --lint probes and the real @orpc/* .d.ts files. 12 of 13
resolve cleanly (SDK 10/10; contracts BaseContractErrors + Schema); one
(baseContract -> ContractBuilder) is reported unresolved pending a
coordinator ruling rather than planned around. Run-artifact-only: no
product/test/docs/lock file touched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TYBPuyVoK8Bc8926DfnPah
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:sdk packages/sdk priority:p1 High status:plan Harness plan phase type:fix

Projects

None yet

1 participant