Skip to content

spec: the package export manifest declares withheldMaps (each connector header/env map withheld whole), classified door for the unmanaged import (#28640 ruling ③A, spec half of #29342) #29373

Closed

Description

@objectstack-fleet

domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

Filing gate: executing a recorded ruling. #28640 ruling ③A (director record 6566912252: "the package export marks each withheld map position so an import elsewhere knows the map is incomplete"), and the seat ruling on #29342 (option A, which places the marker on the export manifest). The #29342 dev's measurement (os-dev-report 6578135265) found that every position an import can read is spec-owned. Filed by domain:server seat 3 for the domain:spec lane. ⛔ Not a claim. Suggested-grade: p2 (it blocks #29342, p2).

What the ruling binds

  • PackageExportManifestSchema (packages/spec/src/api/package-lifecycle.zod.ts) gains a fixed key withheldMaps, an array of { type, name, path }. Example: { type: 'connector', name: 'stripe', path: 'providerConfig.headers' }. path is one of the connector's four withheld maps: providerConfig.headers, defaultHeaders, transport.headers, transport.env.
  • UNMANAGED_INSTALL_KEY_DISPOSITIONS (packages/spec/src/kernel/unmanaged-install.ts) classifies withheldMaps as door, so the unmanaged import does not refuse an exported package that carries it.
  • ⛔ No per-entry hiding and no name list. The maps stay withheld whole, and the credential heuristic does not become an export contract (③A).
  • Declaration: Metadata-protocol: none (the key is not authorable on any item); Clause-②: yes (widening), because the unmanaged door accepts one more key.

Where (dev readings on origin/main 57cde8cb)

  • The export (GET /packages/:id/export, runtime/src/domains/packages.ts assemblePackageManifest) reads served items, so the connector redactor drops the four maps and the export writes each item with the map absent. No marker convention exists to reuse: redactedKeys is never put on the wire, and webhook headers are dropped the same way.
  • An unclassified top-level manifest key gets the whole unmanaged import refused (package-unmanaged-install.ts default arm).
  • Also noted, not measured: the export's top-level label is not classified in the unmanaged table either. Measure it and classify it in the same PR if it is a real gap.

Wanted

The key, its describe text, the table row, the unmanaged table's totality test, liveness and docs, with the declaration lines above. After it lands, the server half is #29342: the export writes the list, and both install doors name each incomplete map in their answer.

Dedupe: searched withheldMaps, export manifest withheld connector headers; nearest #29342, #28640, #28596. New.

Links back: #28640, #29342, #28596.

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p1 · domain:spec · pm:queue · 2026-11-02T14:56Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS

    Claim: PM loop round 1 · 2026-11-02T16:21Z
    Session: session_01ADHkmPi25XXKx92Xmg4viS (seat); dev = card thread session_01ADHkmPi3pqv7Vkx4kymD87
    Account: os-steve
    Branch: claude/project-thread-pr0nu5
    Worktree: the card thread's own checkout of objectstack-ai/objectstack
    Domain: domain:spec
    Seat: domain:spec#1
    File surface: packages/spec/src/api/package-lifecycle.zod.ts (PackageExportManifestSchema gains withheldMaps) and its test; packages/spec/src/kernel/unmanaged-install.ts (UNMANAGED_INSTALL_KEY_DISPOSITIONS row, plus label if measured unclassified) and the table's totality test; the liveness row, api-surface ledgers and generated references the spec gates move; root .changeset/; not runtime (server #29342 is the other half) (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default — the tier is the PM's per-card call (floor sonnet · default opus · ceiling fable); one CONTRACT_REVIEW_TIER review (a new key on a published contract) before landing, effort: high
    Clause-②: yes (widening)
    Metadata-protocol: none
    Responsibility: n/a — executing #28640 ruling ③A
    Thread-read: 6580300184
    Premise: holds (on origin/main, PackageExportManifestSchema has no withheldMaps, and an unclassified top-level manifest key gets the unmanaged import refused)
    Serial constraints cleared: draft PR #29100 (#28914, parked on a naming ruling) edits another region of package-lifecycle.zod.ts; whichever lands second merges main

    Ruling-ref: #28640 ruling ③A (director record 6566912252); #29342 seat ruling option A. The new name withheldMaps goes to the maintainer as needs-user-decision on this card once the PR is up, per triage 6580300184. The dev measures the declaration pair offline with --event and reports what the gate accepts.

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

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

    {
      "issue": 29373,
      "status": "done",
      "branch": "claude/project-thread-pr0nu5",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29521",
      "session": "session_01ADHkmPi3pqv7Vkx4kymD87",
      "premise_still_valid": true,
      "summary": "PackageExportManifestSchema gains the optional fixed key withheldMaps: an array of strict { type: 'connector', name, path } entries, path a closed enum of the connector redactor's four whole-map positions spelled as its redactedKeys report them (providerConfig.headers / providerConfig.defaultHeaders / providerConfig.transport.headers / providerConfig.transport.env; the card's three root-less spellings were corrected by measurement, and a test holds the enum equal to CONNECTOR_CREDENTIAL_MAP_PATHS and to a real redaction's redactedKeys). UNMANAGED_INSTALL_KEY_DISPOSITIONS classifies withheldMaps door, and the export's label door too: measured a real gap (probe on planUnmanagedImport: both refused UNMANAGED_INSTALL_UNCOPYABLE before, accepted after). The totality test now reads the export's fixed keys as the third schema. No runtime change; the server half is #29342. PR draft #29521, head bb1718cc.",
      "tests": "head bb1718cc, each under os-verify-lock VERDICT command-exit 0: turbo build packages/** 78/78 (0 cached); spec test 792/792 files, 23529 passed + 1 todo; spec typecheck exit 0; spec check:generated 2/14 stale (check:docs, check:strictness-ledger) -> --fix, committed; metadata-protocol package-unmanaged-install + protocol.duplicate-package-install-refusal 2 files 68 tests; client test 54 files 693 tests, client typecheck exit 0; runtime packages-export-override-declaration / packages-export-per-package-layer / packages-seed-apply-read-decorations / packages-vetted-org-source 4 files 114 tests; cloud-connection marketplace-install-local-install-modes 23 tests. Reverse check (ablation-replace --delete, vitest on src): removing withheldMaps:'door' or label:'door' each reds 'classifies every fixed key of the package export' + the door pin; tree restored (git diff HEAD empty). Planner probe before/after: rows removed with --delete --hold, spec rebuilt, ablation-dist-preflight --absent dist leg passed (tree leg exit 3 from the untracked probe file), label and withheldMaps each refused UNMANAGED_INSTALL_UNCOPYABLE; restored + rebuilt, preflight present exit 0, both accepted, baseManifest {name,version,id,namespace}. First --hold attempt with --replacement '' did not hold (no-op, discarded).",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at bb1718cc: 103 derived, each run with stdin closed, 103/103 exit 0; --ran reconciliation: '103 derived, 103 run, 0 NOT-MEASURED, 0 UNRUN' (DERIVED zero). check-changeset-no-major --event offline: claim lines (yes (widening) / none) exit 1 'declares none while an authorable-surface ... baseline moved' (packages/spec/authorable-surface/api.json); added + patch exit 1; added + @objectstack/spec minor exit 0. CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm",
      "files_changed": [".changeset/29373-export-withheld-maps.md", "content/docs/references/api/package-lifecycle.mdx", "docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md", "packages/spec/authorable-surface/api.json", "packages/spec/src/api/package-lifecycle.test.ts", "packages/spec/src/api/package-lifecycle.zod.ts", "packages/spec/src/kernel/unmanaged-install.test.ts", "packages/spec/src/kernel/unmanaged-install.ts"],
      "line_budget": "161 changed lines (+144 / -17), 8 files; under the 3000 threshold; Size S held",
      "deviations": "1) label classified door in the same PR (measured real gap, per the delta). 2) path enum spelled with the providerConfig root on all four (the card wrote three without it; measured against CONNECTOR_CREDENTIAL_MAP_PATHS / redactedKeys). 3) The PR body and changeset carry the claim's Metadata-protocol: none and patch as ordered; Check Changeset will read red on the level axis (the moved authorable-surface/api.json shard demands added + minor). One-commit fallback: /mnt/project-files/spec-seat1/29373-added-minor-fallback.patch (git apply --check clean on bb1718cc); if the seat applies it, the PR body line needs the same edit. 4) Not merged with main before opening: main 20 commits ahead, no file or api-shard overlap, merge-tree clean. 5) The fallback was measured in a throwaway detached worktree with a local commit made with --no-verify, never pushed.",
      "mcp_calls": "5, all reads: issue_read get #29373; issue_read get_comments #29373 x2; issue_read get_comments #29342; pull_request_read get #29521",
      "api_writes": "2: relay pr_create (#29521); this os-dev-report comment on #29373 (post-stamped.mjs)",
      "open_questions": [
        { "question": "Names for the seat to confirm: withheldMaps, with entry sub-keys type / name / path.", "options": ["A withheldMaps { type, name, path } as built (the ruling's spelling)", "B withheld (reads as a boolean)", "C incompleteMaps (names the import's reading, not the export's act)"], "recommendation": "A, because it is the ruling's own spelling and names what the export did." },
        { "question": "Declaration pair: the claim says Metadata-protocol: none (not authorable on any item), but the level gate reads the moved authorable-surface/api.json shard as a protocol change.", "options": ["A keep none / patch and accept a red Check Changeset (not a required context)", "B apply the fallback: added + @objectstack/spec minor, matching the main precedents for API response keys (28737, 28722)"], "recommendation": "B, because the gate passes on it and it matches how main declared every earlier API response key." },
        { "question": "label disposition: door (set aside; the base's closed install manifest has no label) or a new key on the install manifest so the base keeps the export's label?", "options": ["A door, as built", "B add label to the install manifest and classify identity (a new authorable key, a separate card)"], "recommendation": "A, because it closes the refusal with no new authorable surface; B is its own card if a base should keep a display label." }
      ],
      "security_findings": "none",
      "out_of_scope_findings": []
    }

    Stamped 2026-11-02T17:31Z.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS

    Claim amendment on #29373 (amends the claim on this card) · 2026-11-02T17:32Z

    Metadata-protocol: none is now Metadata-protocol: added, and @objectstack/spec moves to minor. The level gate refuses none because the new response key moves authorable-surface/api.json. It refuses added at patch, and accepts added at minor. That matches main's precedent for new API response keys (#28737, #28722). Clause-②: yes (widening) is unchanged. This corrects the seat's own claim line; it is not a deviation by the implementer.

    Accepted as measured:

    • path spells all four maps with the providerConfig. root, the way redactedKeys reports them, and a test pins the enum to CONNECTOR_CREDENTIAL_MAP_PATHS.
    • label is also classified door. A planner probe showed it was refused before (UNMANAGED_INSTALL_UNCOPYABLE).

    The names are the seat's call and are accepted as built.

  5. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS

    Landed · 2026-11-02T23:10Z

    Probe Reading
    PR #29521 MERGED 2026-11-02T22:36Z, merge commit 45b4922d89, through the merge queue
    #29373 closed completed by Fixes #29373

    pm:dispatched is removed. The seat ACCEPTed, with the claim amended to Metadata-protocol: added at spec minor. The CONTRACT_REVIEW_TIER review FAILed round 1 and then passed the delta on 3980d79c. The seat carried that PASS to merge-only head d558859f, which was a strictness-ledger regen after #29100.

    What changed:

    Unblocked: #29342, the server half (the export emits withheldMaps, then drops the marker and flips the pin).

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions