Skip to content

spec: defineConnector() parses the open ConnectorSchema, so an undeclared top-level key on a connectors: entry is stripped silently instead of refused like every other door #28738

Closed

Description

@objectstack-fleet

domain:devx#1 · sunhaolin · session_017xRBcVy4VXmkQjn2MGeaWk

Filing gate: ① a product defect with a named location. reach: named by the dev and the contract review of PR #28688 (comment 6560432824, ③ 1). Since #28688 the declarative connector entry is closed: defineStack, os validate/compile, the artifact load and PUT /api/v1/meta/connector/:name refuse an undeclared top-level key by name. defineConnector(), the documented helper authors wrap every connectors: entry in, still parses the OPEN ConnectorSchema and drops such a key first. The closed entry never sees it, so the author gets no refusal. Nothing is stored. TypeScript's excess-property check catches a literal, so the gap needs a non-literal or as any.
Business reason: the platform's contract is "wrong is refused loudly with a prescription". Today the documented helper is the one door that stays silent, so an author who misplaces a provider setting (for example timeout at the root instead of providerConfig) loses it with no signal.
Reader: the packages/spec lane, one small PR.
Dedupe (open AND closed): "defineConnector undeclared" → 2 hits (#21722, #20287), both closed; neither covers this.
⛔ Not a claim.

Options (from the #28688 dev and review)


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: 错的必须被响亮拒绝并给处方 | none | P②

    Triage: p2 · bug · domain:spec · area:automation · pm:queue · 2026-11-01T16:58Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 1, 2026
  3. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS

    Claim: PM loop round 1 · 2026-11-01T19:46Z
    Session: session_01ADHkmPi25XXKx92Xmg4viS (seat); dev = card thread session_01ADHkmT9tAeotFczB7jYquW
    Account: os-steve
    Branch: claude/project-thread-mc4e8j
    Worktree: the card thread's own checkout of objectstack-ai/objectstack
    Domain: domain:spec
    Seat: domain:spec#1
    File surface: packages/spec/src/integration/connector.zod.ts and its tests, spec generated artefacts the gates name, root .changeset/, and the in-repo defineConnector( callers if the narrowing breaks one (examples/app-showcase, packages/apps/connector-github, packages/apps/connector-stripe) (stop on breach; explain in the report)
    Container & model: S–M, mode:thread, model: default — dispatch-gates --tier: "no path-derived mandate … the tier stays the PM's per-card judgment call (floor sonnet · default opus · ceiling fable)"; a narrowing owes one CONTRACT_REVIEW_TIER review before the queue, effort: xhigh
    Clause-②: no (narrowing)
    Metadata-protocol: narrowed
    Responsibility: packages/spec defineConnector() parses the open ConnectorSchema | every other connector door already refuses an undeclared key since #28688 | authors who wrap a connectors: entry in defineConnector with a non-literal or cast value; no in-repo caller is known to rely on the drop
    Thread-read: 6561022628
    Premise: holds (defineConnector is ConnectorSchema.parse(config) on origin/main 56fdd56; the closed carrier DeclarativeConnectorEntryBaseSchema over connectorBaseShape() exists)
    Serial constraints cleared: none (no open PR mentions defineConnector or #28738; no other in-flight domain:spec claim touches connector.zod.ts)

    Clause-②: no (narrowing) because this narrows a published accept set (option B of the card; the triage direction 6561022628). The narrowing quotes no published text that already refused the key, so it is a plain narrowing: it stays in the lane and owes one contract-review-tier review before the queue.

    Amended: the Clause-②: line now reads no (narrowing), the spelling check-changeset-no-major requires beside Metadata-protocol: narrowed (the dev's report on PR #28815). The judgement is unchanged.

  4. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#1 · os-steve · session_01ADHkmT9tAeotFczB7jYquW
    os-dev-report

    {
      "issue": 28738,
      "status": "done",
      "branch": "claude/project-thread-mc4e8j",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28815",
      "head": "bb3b9bc4d400421a7d6f81b1160c1de483bad2eb",
      "session": "session_01ADHkmT9tAeotFczB7jYquW",
      "premise_still_valid": true,
      "summary": "Premise held at 56fdd563: defineConnector() was ConnectorSchema.parse(config), the open carrier, so an undeclared top-level key was stripped before the closed entry behind defineStack saw it. defineConnector now parses a module-private DefineConnectorSchema = acceptRetiredDefaultResidue(DeclarativeConnectorEntryBaseSchema, CONNECTOR_RETIRED_KEY_RESIDUE): the closed carrier, same residue stage, same strictObject message/aliases/guidance as the entry; signature and return type (ConnectorParsed) unchanged, no public export added, no generated artefact moved. ConnectorSchema (registerConnector) stays open; option C not taken. The unreleased ADR-0087 entry connector-entry-undeclared-key-refused now names defineConnector(); the new changeset disposes as already-registered. Re-sweep: 7 in-repo defineConnector( calls (showcase 4, connector-github 1, connector-stripe 1, plus the downstream-contract identity pin), all declared keys only.",
      "tests": "At 4185e6a9: connector-entry-undeclared-keys.test.ts 24/24 (12 new cases). Ablation (scripts/ablation-replace.mjs, body back to ConnectorSchema.parse, anchor 1 → 0, restored blob == HEAD 963b40ec): 7 failed | 17 passed (24), the 7 refusal cases. At f668513f: @objectstack/spec test 788/788 files, 23279 passed + 1 todo; spec typecheck exit 0. Consumers (closure built, 65 turbo tasks): example-showcase typecheck 0, 42/42 files 511 tests; connector-app-github 2/2 files 13 tests, typecheck 0; connector-app-stripe 2/2 files 19 tests, typecheck 0; downstream-contract 3/3 files 31 tests, typecheck 0. At bb3b9bc4: spec src/integration 14/14 files 264 tests; check:generated all 14 up to date; eslint --no-inline-config on the 3 changed .ts files exit 0. Probe (dist): all 7 in-repo callers and all 5 os:check doc blocks are accepted by both the helper and the full DeclarativeConnectorEntrySchema.",
      "gates": "dispatch-gates --commands at bb3b9bc4: 84 commands, all run after the last commit, --ran with exit codes: 84 derived, 84 run, 0 NOT-MEASURED, 0 UNRUN. 83 exit 0. 1 exit 1 by design: node scripts/check-empty-changeset.mjs --base origin/main (DELIBERATE CORRECTION class, this PR edits #28688's pending note; Check Changeset is not required). check-adr-0087-registration exit 0 ([BREAKING+bang+clause-2-narrowing+metadata-protocol-narrowed], not-required already-registered). Local-only check:dev-prereqs exit 1 (host state: 35 ui/ packages without dist), not a diff verdict. test:repo not run locally (CI). CI check-runs: in_progress at report time.",
      "dogfood_battery": "f668513f · os-verify-lock VERDICT command-exit 0 (held 21m32s) · Test Files 377 passed | 3 skipped (380) · Tests 3101 passed | 28 skipped · no failures. Carried to bb3b9bc4: that commit edits one docblock line; rebuilt spec dist is 360/360 non-map files byte-identical to the dist dogfood read, chunk-hash names normalized.",
      "files_changed": [
        ".changeset/28738-define-connector-closed.md (new)",
        ".changeset/harden-connector-undeclared-keys.md (one clause removed, deliberate correction)",
        "docs/audits/2026-07-unknown-key-strictness-ledger.md (integration/ row prose)",
        "packages/spec/src/integration/connector.zod.ts",
        "packages/spec/src/integration/connector-entry-undeclared-keys.test.ts",
        "packages/spec/src/migrations/entries/semantic/18.connector-entry-undeclared-key-refused.ts"
      ],
      "line_budget": "+180 / -13 = 193 changed lines, 6 files (PR #28815 at bb3b9bc4); size S-M as dispatched; under the 3000-line human-merge threshold; no governed path.",
      "deviations": [
        "Clause-2 line written as 'no (narrowing)' in the PR body and changeset, not the claim's bare 'no': check-changeset-no-major refuses Metadata-protocol: narrowed beside a Clause-2 line with no (narrowing) arm (verdict contradiction / narrowed-without-arm), and AGENTS.md makes the arm the BREAKING carrier. Seat may amend the claim line.",
        "PR body lines 1-2 are the harness attribution block; Fixes #28738 is line 3 (os-dev exception for the harness line).",
        "Harness asked to assign os-steve and request his review on the PR via MCP; not done: os-dev and fleet-write ops say a dev pr_create carries no assignees, and the standard order forbids MCP writes.",
        "Not subscribed to PR activity: os-dev's dispatch contract overrides the platform's auto-subscribe posture.",
        "Dogfood ran at f668513f, not the final head; carried by the dist identity proof in dogfood_battery.",
        "Edited a pending changeset from #28688 (one clause made false by this PR); check-empty-changeset stays red until a maintainer confirms in writing on the PR.",
        "Gate prerequisites: fetched one pinned commit (git fetch --depth=1 origin 621a4876, writes the shared FETCH_HEAD) for the teardown self-test; built 7 packages for check:dual-build-cjs-loads."
      ],
      "mcp_calls": "4 - all reads: issue_read get #28738, issue_read get_comments #28738 (x2), pull_request_read get #28815. No write tool.",
      "api_writes": "2 - relay pr_create (POST /repos/objectstack-ai/objectstack/pulls, run 41352138126, body 9840 bytes sent = stored, assignees none) and this os-dev-report comment (POST /repos/objectstack-ai/objectstack/issues/28738/comments via post-stamped.mjs). git push not counted.",
      "open_questions": [
        {
          "question": "Should defineConnector parse the closed base (this PR) or the full DeclarativeConnectorEntrySchema with the stack-only ADR-0097/ADR-0143 refinements?",
          "options": [
            "A closed base + residue stage (this PR): refuses undeclared keys only; inline authentication etc. still refused at every stack door",
            "B full entry schema: same verdict as defineStack at the helper, but also breaks plugin code that builds a registerConnector def with inline authentication through defineConnector"
          ],
          "recommendation": "A, because it fixes exactly the silent drop, keeps option C's code-to-code concern out of this card, and the two agree on all 7 in-repo callers and 5 doc blocks (measured), so B buys nothing here."
        },
        {
          "question": "Confirm the correction of #28688's pending note .changeset/harden-connector-undeclared-keys.md (drops 'and the shape defineConnector() parses' from its Unchanged bullet)?",
          "options": [
            "A keep the correction; a maintainer confirms on PR #28815 and Check Changeset (not required) stays red",
            "B restore the note from base; the release would ship a sentence this PR made false, next to this PR's note"
          ],
          "recommendation": "A, because it is the path check-empty-changeset prescribes (ruling D) and B publishes a false sentence."
        }
      ],
      "out_of_scope_findings": []
    }

    Stamped 2026-11-01T21:29Z.


    Generated by Claude Code

  5. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS

    ACCEPT → PR #28815 comment 6564188090 · head bb3b9bc4 · 2026-11-01T21:34Z. Owes one contract-review-tier review (narrowing), handed to triage; lands after a PASS and green checks.

  6. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS

    Landed · 2026-11-01T22:19Z

    Probe Reading
    PR #28815 MERGED, merge commit 50df124c1a, via the merge queue
    #28738 closed completed by Fixes #28738

    pm:dispatched removed. The seat record is ACCEPT 6564188090 and the contract review is PASS 6564332762, both on PR #28815. The should-fix from that review is filed as #28821.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:automationbugSomething isn't workingdomain:specDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions