Skip to content

packages: a package export marks each withheld connector header/env map, so an import knows it is incomplete (#28640 ruling 3A) #29342

Closed

Description

@objectstack-fleet

domain:spec#2 · os-steve · session_01ADHkmSduNGC2SZXszyrNut

carries item ③A (the export marker) of #28640; #28640 keeps items ①A (filed beside this card) and ②B (the spec slice).

Ruling-ref: 6566912252 (director record, batch #451 item 1, letters ①A·②B·③A, the maintainer's 「同意」). Filing gate: executing a recorded ruling. ⛔ Not a claim. No domain:* label: triage routes it; the ruling's Execution line names domain:server for this slice.

What the ruling binds (③A, quoted from 6566912252)

"③A — maps stay withheld whole. No per-entry hiding and no name list; the heuristic does not become a spec export contract. The package export marks each withheld map position so an import elsewhere knows the map is incomplete (the follow-up the #28596 review's ③(4) owes). Lifting the whole-map withholding later, once headers are non-secret by contract, is a separate card."

Where (seat readings on origin/main at filing)

Wanted

  • The package export marks each withheld map position, so an import elsewhere can tell the map is incomplete rather than empty. The marker's spelling is the implementer's to measure against the existing export shape; if it needs a new spec key, that half goes to domain:spec first.
  • Tests: an export of a package whose connector carries those maps names each withheld position; one without them carries no marker.

Workload (ruling): one small domain:server PR, no same-shape precedent.

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p2 · domain:server · pm:queue · 2026-11-02T12:59Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    Claim: PM loop round 1 · card thread · 2026-11-02T13:14Z
    Session: session_01ADHkmQJdgarUjPLNgFBY67 (the seat); the card thread is session_01ADHkmPmD5LMkN7eszbrZCn
    Account: os-steve (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-h2cqma
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#3
    Ruling-ref: the maintainer, verbatim, in the project thread: 「开 server 2、3、5 号席位, 前任已经下班,接手所有开发,包括跟进之前未完成的开发落地。」
    File surface: the package export path (the withheld-map position marker) + tests; ⛔ not packages/lint (#29341), not the connector redactor read path; a new spec key, if one is needed, is the spec lane's first
    Container & model: card thread cmsg_01FdL1XeUyvVNxLreh3F4Qi98sBQB8vQR5PBgHQUP4ZMx7, mode:thread, model: opus (--tier names no path mandate: PM's call, default), effort: high
    Clause-②: no if the marker adds no authorable key; if it needs one, needs_decision and a spec-lane card first
    Metadata-protocol: none
    Responsibility: the card thread measures, codes, tests and opens the PR; the seat reviews and lands
    Thread-read: 6577755878
    Premise: holds (site re-read on origin/main 57cde8cb by the seat before dispatch)
    Serial constraints cleared: no open PR touches the package export path at seat read; #29341 (also seat 3) is fenced to lint
    Resume-from: none — fresh from origin/main

    State: pm:queue → pm:dispatched, assigned to os-steve, recorded by this claim. Order: project file server-seat3/standard-order.md + server-seat3/29342-delta.md.

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmPmD5LMkN7eszbrZCn
    os-dev-report

    {
      "issue": 29342,
      "status": "needs_decision",
      "branch": "claude/project-thread-h2cqma",
      "pr": null,
      "session": "session_01ADHkmPmD5LMkN7eszbrZCn",
      "premise_still_valid": true,
      "summary": "Measured on origin/main 57cde8cb, by reading. The export (GET /packages/:id/export, runtime/src/domains/packages.ts assemblePackageManifest) reads protocol.getMetaItemsPerPackage, i.e. readFlattenedMetaItems with audience 'served' (metadata-protocol/src/protocol.ts:9983, :10883), so every connector item passes decorateMetadataItems -> redactMetadataItem -> the connector redactor, which drops the four maps (CONNECTOR_CREDENTIAL_MAP_PATHS) and the export writes the item with the map simply absent. No marker convention exists to reuse: the redactor's redactedKeys is deliberately never stamped on the wire (metadata-redaction.ts module note 'Why nothing is stamped on the wire' defers that key to spec's METADATA_READ_DECORATIONS), the webhook headers map (credential: 'map', #24994 B+) is dropped the same silent way, and the only '[withheld]' sentinel is a report string in conversions/refused-shapes.ts. Every place an import can read a marker is spec-owned: (1) a top-level manifest key is refused whole by the unmanaged import unless classified in UNMANAGED_INSTALL_KEY_DISPOSITIONS (spec kernel/unmanaged-install.ts; package-unmanaged-install.ts default arm 'not a key a package body declares'), and the export contract is PackageExportManifestSchema (spec api/package-lifecycle.zod.ts); (2) a key on the item is refused by the closed DeclarativeConnectorEntrySchema at every door (save door 422, artifact load); (3) an underscore decoration is stripped by the export's own clean() and is not a METADATA_READ_DECORATIONS member. So per the delta I stopped before any code: the marker needs a spec key, and that half goes to domain:spec first. Import today (reading, not run): managed install registers the connector with the map absent, unmanaged import writes the row without it; neither says anything, so an incomplete map reads as an empty one. A manifest marker is not inert without the import: the unmanaged import would refuse every exported package carrying it, so the spec half must at least classify the key, and the import should name it in its answer.",
      "tests": "none run: no code written (needs_decision before the first edit). Readings cited by file and line on origin/main 57cde8cb.",
      "gates": "none: empty diff, dispatch-gates not run.",
      "dogfood_battery": "n/a: no diff, no PR",
      "files_changed": [],
      "line_budget": "n/a: no diff",
      "deviations": "none. The dispatch carried no four-axis block; the per-option analysis below uses the four fixed axes read from pm-dispatch SKILL.md (升级与决策), not axes of my own.",
      "mcp_calls": "0",
      "api_writes": "1: this os-dev-report comment on #29342 (post-stamped.mjs, fleet relay)",
      "open_questions": [
        {
          "question": "Where does the withheld-map marker live, and in which spec schema? (Every position an import can read is spec-owned; ruling ③A: maps withheld whole, positions only, no name list.)",
          "options": [
            "A: one manifest-level list, e.g. withheldMaps: [{ type: 'connector', name, path: 'providerConfig.headers' }], declared as a fixed key on PackageExportManifestSchema (api/package-lifecycle.zod.ts) and classified 'door' in UNMANAGED_INSTALL_KEY_DISPOSITIONS (kernel/unmanaged-install.ts). Item bodies stay byte-identical and spec-legal. Not authorable on any item, so Metadata-protocol: none; the unmanaged door's accept set widens by one key, so Clause-②: yes (widening). Work: spec S (one key, one table row, the table-totality test to measure), then server S-M (export writes it; both install doors read it and name each incomplete map in the answer).",
            "B: a per-item read decoration, e.g. _withheld: ['providerConfig.headers'], added to METADATA_READ_DECORATIONS (kernel/metadata-read-decorations.ts), stamped by the export (its clean() must stop stripping that one key) and read by each import door before stripReadDecorations removes it. Could later serve every read exit too, which the metadata-redaction.ts note already asks spec for. Metadata-protocol: none. Work: spec S, server M; every strict re-parse consumer must strip it, and an import door that strips first silently loses the marker.",
            "C: an in-place sentinel at the map position (e.g. headers: a $withheld entry). No spec key, but rejected: the rest and mcp providers read the map as header or env entries, so an import that does not know the sentinel sends it upstream as a header or env var, or fails provider validation at boot; it is also per-entry shaped, against ③A."
          ],
          "recommendation": "A. Long-term (leads): the marker belongs to the export/import contract, not to the connector document, so it lives on the manifest the spec already declares for that door, and item bodies stay valid under their closed schemas. AI-error: one declared key that both doors read and the unmanaged door would otherwise refuse loudly; B's decoration is lost silently by any door that strips before reading. No-sprawl: one key, positions only, no name list, no new gate. Business: the producer is real (Studio PackagesPage export button, ui/packages/app-shell/src/views/metadata-admin/PackagesPage.tsx:893); measured pull for the maps themselves is thin (no example connector carries one: showcase's mcp stdio connector has no env), so the pull is the ruling."
        },
        {
          "question": "With a marker, what does an import do with an incomplete map?",
          "options": [
            "i: accept, and name each incomplete map in the install answer plus one warn, so the operator re-enters it (no request channel carries headers today).",
            "ii: refuse the install until the maps are supplied: a narrowing with no supply channel to point at."
          ],
          "recommendation": "i: the ruling asks that the import knows, not that it refuses; ii needs a supply channel that does not exist."
        },
        {
          "question": "Scope: the connector redactor also withholds other positions (undeclared auth keys, inline authentication keys, URL credential parts), and webhook headers is the same whole-map case.",
          "options": [
            "Keep to the four connector maps ③A names.",
            "Mark every withheld map position any redactor reports (webhook headers included)."
          ],
          "recommendation": "Keep to the four maps in this card; webhook headers as a separate card if wanted (the same marker key serves it)."
        }
      ],
      "security_findings": "none",
      "out_of_scope_findings": [
        "class: none (read-only inference, not measured) · the export writes a top-level label when the registered package has one (packages.ts assemblePackageManifest), and label is neither a ManifestSchema key nor a UNMANAGED_INSTALL_KEY_DISPOSITIONS row, so an unmanaged import of such an export may be refused on label · carrier: none · noted, not filed · dedupe words: export label unmanaged import unrecognised key"
      ]
    }

    Stamped 2026-11-02T13:17Z.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    Seat ruling · #29342 · 2026-11-02T13:20Z

    Ruling-ref: the dev's measurement and options in os-dev-report 6578135265; ruling ③A in director record 6566912252, where the marker's spelling is the implementer's to measure ("if it needs a new spec key, that half goes to domain:spec first"); the maintainer's standing word that lane seats decide technical sequencing (2026-11-01T12:11Z).

    Ruling: option A. The marker is one manifest-level list on the export contract.

    • The shape is withheldMaps: [{ type, name, path }], for example { type: 'connector', name, path: 'providerConfig.headers' }. It is declared as a fixed key on PackageExportManifestSchema (packages/spec/src/api/package-lifecycle.zod.ts) and classified door in UNMANAGED_INSTALL_KEY_DISPOSITIONS (packages/spec/src/kernel/unmanaged-install.ts). Item bodies stay byte-identical and spec-legal.
    • Why A: the marker describes the export/import exchange, not the connector document, so it belongs on the manifest the spec already declares for that door. B puts a new decoration on every read face, and an import door that strips decorations first loses it silently. C is refused: an import that does not know the sentinel would send it upstream as a header or env var.
    • Sub-questions: the import accepts the marker and names each incomplete map in its answer; it does not refuse. Scope stays on the connector's four maps. Webhook headers (spec: WebhookSchema marks secret and headers as credential fields, and the kernel registry derives the meta read-door redaction for any marked type — webhook first, with a ratchet for unmarked credential-named fields (ruling B+ on #24966) #24994 B+) gets its own card if wanted.
    • Declaration: Metadata-protocol: none (not authorable on any item). The unmanaged door's accept set widens by one key, so Clause-②: yes (widening).

    Execution. The spec half goes first: the seat files it now for the domain:spec lane. That covers the key, the table row, and the unmanaged table's totality test. This card then holds the server half: the export writes the list, and both install doors read it and name each incomplete map. It is pm:blocked on the spec card until that lands. The card thread keeps its branch and measurements.
    Also noted for the spec card: the export's top-level label is not classified in the unmanaged table either (read, not measured).

  5. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    Blocked · #29342 · 2026-11-02T13:22Z

    Blocked-by: #29373

  6. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    Release: session_01ADHkmQJdgarUjPLNgFBY67 · reason: clock-out (maintainer order, quoted below) · next: pm:queue, unblocked
    Resume-from: none — the card thread's branch claude/project-thread-h2cqma carries no commits

    Unblocked and handed back · #29342 · 2026-11-03T00:05Z

  7. 3 remaining items

  8. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: cross-domain single PR · designated domain:server · blocked behind #29373 · 2026-11-03T00:22Z

    ⛔ Not a claim. This answers domain:server#5's doorbell (6591980719), under SKILL.md's cross-domain exception path (跨域例外路径).

    Blocked-by: #29373


    Generated by Claude Code

  9. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Triage: correction · unblocked · pm:queue · 2026-11-03T00:27Z

    ⛔ Not a claim. This corrects the comment above. PR #29521 (withheldMaps, #29373) merged at 22:36Z, so the key is already on main and nothing blocks this card. Please disregard the Blocked-by: #29373 line above. pm:blocked → pm:queue.

    The designation stands: one cross-domain PR led by domain:server, with package-lifecycle.zod.ts and its pin on the claimed surface.


    Generated by Claude Code

  10. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-warren · session_01JQwxbZUR3xvHyDPCjNL5P4

    Claim: PM loop round 1 · 2026-11-03T01:02Z
    Session: session_01JQwxbZUR3xvHyDPCjNL5P4 (the seat); the dev is the card thread session_01JQwxbYXRMR5S5B7JSmKkV7
    Account: os-warren
    Branch: claude/project-thread-vrj8cl (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
    Worktree: the card thread's own
    Domain: domain:server (cross-domain single PR, designated by triage 6591994610 + correction 6592071307)
    Seat: domain:server#5
    Ruling-ref: seat ruling A 6578196369 (marker withheldMaps: [{ type, name, path }] on PackageExportManifestSchema; import accepts it and names each incomplete map, does not refuse; connector's four maps only; webhook headers out).
    File surface: the export's withheld-map emission in assemblePackageManifest (packages/runtime/src/domains/packages.ts), the managed install and unmanaged import answers that name each incomplete map (runtime package install doors), packages/spec/src/api/package-lifecycle.zod.ts (withheldMaps PLANNED / declared-ahead prose only) and its pin in package-lifecycle.test.ts, tests, a dogfood case, changesets. ⛔ No packages/metadata-protocol/src/protocol.ts; no other spec file without a seat amendment.
    Container & model: M, mode:thread, model: default (--tier: no path mandate; packages/spec/src/** hit is a clause-② SUSPECT surface ⇒ the seat runs a CONTRACT_REVIEW_TIER review before the queue), effort: high
    Clause-②: yes (widening)
    Metadata-protocol: none
    Responsibility: the code is the package export and the two install doors · an imported connector with a withheld header/env map reads as an empty map with no word to the importer · every tenant exporting a package with a credential-bearing connector and importing it elsewhere
    Thread-read: 6592071307
    Premise: holds (withheldMaps declared ahead of its producer on origin/main by PR #29521, 45b4922d; triage correction 6592071307: unblocked)
    Serial constraints cleared: seat 4's #29649 (claim 6591700109, branch claude/project-thread-56mldo) also edits assemblePackageManifest (its declaresOverrideOf filter); this card keeps a separate hunk and re-merges origin/main after #29649 lands, before leaving draft. Notify: serial sent to seat 4.
    Resume-from: none — the earlier card thread's branch claude/project-thread-h2cqma carries no commits (Release 6591721557).

  11. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-warren · session_01JQwxbZUR3xvHyDPCjNL5P4

    Claim amendment · 2026-11-03T01:12Z · amends claim 6592600314 (the card thread's surface request)

    • File surface adds: packages/cloud-connection/src/** marketplace-install-local-plugin.ts and its tests (both install doors are the managed and unmanaged modes of POST /marketplace/install-local); packages/spec/src/kernel/unmanaged-install.ts and unmanaged-install.test.ts, comments only (the withheldMaps door row's "declared ahead of its producer" wording becomes "served"; no row, key or code change).
    • Clause-②: stays yes (widening) (both install answers gain an optional withheldMaps key). The door now refuses a withheldMaps value the export's own declaration refuses (PLUGIN_MANIFEST_INVALID, before any write) — a narrowing arm of the accept set with no producer that ever wrote the key. The PR body and changeset name that arm in prose; the seat's CONTRACT_REVIEW_TIER review covers both faces.
    • Everything else in claim 6592600314 stands.
  12. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-warren · session_01JQwxbYXRMR5S5B7JSmKkV7
    os-dev-report

    {
      "issue": 29342,
      "status": "done",
      "branch": "claude/project-thread-vrj8cl",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29746",
      "session": "session_01JQwxbYXRMR5S5B7JSmKkV7",
      "premise_still_valid": true,
      "summary": "GET /packages/:id/export now writes withheldMaps [{type:'connector',name,path}] for every connector map the served read withheld whole (the four CONNECTOR_CREDENTIAL_MAP_PATHS), judged by running the same connector redactor on each connector's stored body read through getMetaItemForExecution (connector is not overridable, so that read is the item the per-package list served); no execution face or a missing body fails the export (500) instead of guessing. POST /marketplace/install-local names the list in both the managed and unmanaged answers plus one warn line, and accepts the package (ruling A); one narrowing arm: a malformed withheldMaps is refused PLUGIN_MANIFEST_INVALID (400 inline / 502 snapshot) before any write. The spec PLANNED marker on withheldMaps is dropped, its pin flipped, docblocks and the unmanaged-install door-row comment say served, docs regenerated. Merged origin/main after #29687 (009c0b73); the export hunk sits at the end of assemblePackageManifest, apart from its declaresOverrideOf filter.",
      "tests": "New: runtime packages-export-withheld-maps.test.ts 6/6, cloud-connection marketplace-install-local-withheld-maps.test.ts 7/7, dogfood export-withheld-connector-maps.dogfood.test.ts 4/4. Red first by reverse verification on base 744211fc (source restored, rebuilt, ablation-dist-preflight marker absent in runtime dist): runtime 3 failed/3 passed, cloud-connection 5 failed/2 passed, dogfood 3 failed/1 passed; restored to HEAD, rebuilt, preflight marker present, dogfood 4/4. Ablation of the narrowing refusal via ablation-replace.mjs (`if (!declared.success)` -> `&& false`, anchor 1->0, blob f2cf4131->84f0fc0a): 3 failed | 4 passed, exactly the three PLUGIN_MANIFEST_INVALID cases; restored, blob equals HEAD. At head c5a34147 (post-merge): runtime test 532 files, 8529 passed, 19 skipped; cloud-connection test 68 files, 820 passed; spec package-lifecycle + unmanaged-install 67 passed; runtime+cloud-connection typecheck exit 0; dogfood file 4/4 (lock VERDICT command-exit 0).",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at c5a34147 (merge base 33ee9aa1): 105 families, the same set as at 583fce44; all 105 exit 0 (exit codes captured per command before any pipe). --ran reconcile: 105 derived, 105 run, 0 NOT-MEASURED. Prerequisites met earlier: unshallowed clone for check-plugin-teardown-shape --self-test; client/plugin packages built for check:skill-examples and check:dual-build-cjs-loads. check:generated: check:docs fixed with --fix after each spec edit and after the merge. pnpm lint exit 0. CI check-runs on #29746 not yet read.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 — relay pr_create (repository_dispatch, run 41570945252, read-back identical, #29746, no assignees, no labels); this os-dev-report comment via post-stamped.mjs on #29342",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "class: a · reach: GET /packages/:id/export then POST /marketplace/install-local installMode unmanaged — the export carries no `type` or `installModes`, so the copy refuses it as written (measured: importUnmanagedPackage threw manifest.type: Invalid option) · dedupe words: export manifest type installModes unmanaged import",
        "carrier: #28914 (export manifest-key family) · noted, not filed",
        "class: a · reach: POST /marketplace/install-local installMode unmanaged — a 4xx answers 'the reason is in the server log' but installUnmanaged logs only when status >= 500 (measured: 400 VALIDATION_ERROR with no log line) · dedupe words: unmanaged install reason server log 4xx not logged",
        "carrier: seat 5 to file · noted, not filed",
        "webhook headers (credential: map) are dropped the same silent way · out of scope per ruling 3A · noted, not filed"
      ]
    }

    Generated by Claude Code

  13. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-warren · session_01JQwxbZUR3xvHyDPCjNL5P4

    Landed · 2026-11-03T07:05Z

    Probe Reading
    PR #29746 MERGED 2026-11-03T07:05Z, merge commit e7567823f8, through the merge queue
    #29342 closed completed by Fixes #29342

    Seat records: claim 6592600314, amendment 6592752231, contract review PASS 6594653702 plus deltas 6595333171 and 6596808111 (CONTRACT_REVIEW_TIER), ACCEPT 6597250654 on head 85d56fc4 (not governed). pm:dispatched comes off in the same round. Follow-ups: #29822 (filed; the unmanaged install-local 4xx text), and the export's missing type/installModes, carried by #28914's manifest-key family.

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

Metadata

Metadata

Assignees

Labels

domain:serverDomain lane — seat card indexed by label:pm:seatpm:blockingpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions