Skip to content

connector apps, E4 batch 1 (static key): GitHub over its remote MCP server and Stripe read over its OpenAPI document, as open-edition metadata packages validated by this repository's CI #28276

Open
1 of 1 issue completed

Description

@objectstack-fleet

epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U

Filing gate: ④ coordination child of #27293 (E4), filed by the epic PM on the ruling of #27302. Ruling-ref: 6486157794 (letter A, phased; maintainer 「同意」 2026-10-29). Child of #27293. ⛔ Not a claim.

What the ruling binds

Verbatim from 6486157794: "an app whose every key runs on the open tier is open edition and lives in this repository (a metadata package validated by this repository's CI against the runtime at HEAD) … start with only the apps #27293's Done-when needs — DocuSign for the OAuth path plus two or three static-key apps — and grow toward 20–30 on customer pull, batch by batch (static-key; OAuth after #26702; signature after #26710)."

This card is the static-key batch. The two apps are the epic PM's pick within that ruling, the ones recommended to the maintainer on 2026-10-29: each exercises a different provider archetype the E3 recipes teach.

App Provider Credential the administrator supplies Why first
GitHub mcp, remote HTTP transport, include allowlist a personal access token in a header, through the credential store (#27237) proves the remote-MCP archetype; nothing it needs is undelivered
Stripe (read only) openapi, the document normalized by #27373's script, providerConfig.include (#26709 item 1) a restricted secret key, read scopes proves the OpenAPI archetype; stripe/openapi is MIT; write operations are form-encoded, which the provider does not send, so read only

Work (per app)

  • A metadata package: the declarative connectors: entry, credentialRef (no secret in metadata), one or two flows or ai: { exposed: true } actions showing it used, the listing file (objectstack.manifest.json) and a README whose credentials section names each credential, where to obtain it and its scopes (the handbook, content/docs/deployment/marketplace-handbook.mdx).
  • Stripe: the packaged spec is the output of pnpm --filter @objectstack/connector-openapi normalize-openapi with an --include-pattern; the README records the upstream, commit and sha256 the script printed ([Epic] Marketplace and connector auto-shelf — E1 platform prerequisites (openapi/mcp hardening, outbound OAuth, request signing), E2 administrator credential hand-off, E3 author recipes and handbook, E4 the first shelf of official connector apps #27293's Done-when "provenance (upstream, commit, sha256)").
  • Validated by this repository's CI at HEAD: os validate and a boot test that materializes the instance against a fixture (no live vendor call in CI); one live sandbox call run once locally and reported.
  • Home: a new workspace directory for official connector apps (for example packages/connector-apps/<vendor>/, with its glob added to pnpm-workspace.yaml), npm-private. ⛔ The exact home is the triage seat's call at first touch; the card names the candidate so the lane can price it.

Reader

The triage seat confirms the home and lane (the ruling's workload names domain:devx); the epic PM of #27293 dispatches. The ingestion pipeline and listing generation are cloud-repository work and are not in this card.

Dedupe

The 500 most recent issues and PRs (all states, read 2026-10-31T02:05Z), titles grepped for connector app|shelf|docusign|stripe|github mcp|E4: 0 hits; control connector on the same set: 47 hits.

Activity

  1. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: 发布并装进一个环境 | none | P④

    Triage: p2 · domain:server · area:automation · pm:epic kept · 2026-10-31T02:54Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U

    Claim: PM loop round 3
    Session: session_017xRBcVBKAFk1ntXSjvPt7U
    Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-28276-connector-apps-batch1
    Worktree: objectstack-issue-28276
    Domain: domain:server
    Seat: epic:#27293#1
    File surface: packages/apps/connector-github/** and packages/apps/connector-stripe/** (new metadata packages, npm-private, under the existing packages/apps/* workspace glob — the lane table already routes packages/apps/* "by where it lands", so no new glob and no lane-table edit), pnpm-lock.yaml (regenerated by pnpm install, never by hand) (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus (TIER_DEFAULT — dispatch-gates --tier --repo objectstack-ai/objectstack this fire: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6538071305
    Ruling-ref: 6486157794
    Premise: holds (read at origin/main 69ce01d7 2026-10-31T03:02Z: packages/apps/ holds account, setup, studio only; every key the two apps need is delivered — mcp include refusals (#27402), openapi providerConfig.include (#27387), the normalizer (#27436), the credential store (#27237) and page (#27238) all merged)
    Serial constraints cleared: none — none of the 60 most recent open PRs touches packages/apps/connector-* or pnpm-workspace.yaml; #27401's branch (68d8770f, in the decision box) touches connector-mcp source, not these packages.

  3. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
    os-dev-report

    {
      "issue": 28276,
      "status": "needs_decision",
      "branch": "claude/issue-28276-connector-apps-batch1",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28306",
      "session": "session_017xRBcVBKAFk1ntXSjvPt7U",
      "premise_still_valid": true,
      "summary": "GitHub half delivered in draft PR #28306 (Part of #28276): new npm-private package packages/apps/connector-github (@objectstack/connector-app-github). It declares a provider mcp connector over GitHub's remote MCP server: http transport https://api.githubcopilot.com/mcp/ with X-MCP-Readonly true, include [search_issues, issue_read], and bearer auth with credentialRef GITHUB_MCP_TOKEN, all read from github/github-mcp-server at f2a07cd1, not from memory. It also adds two flows that use it, objectstack.manifest.json, and a README whose Credentials section names the token, where to get it and its scopes. CI validates it at HEAD: the test script is objectstack validate && vitest run, and a bootStack boot test runs against a fake MCP client. The Stripe half is NOT in the PR and needs a decision (open_questions[0]). The PM's mechanism assumption is disproved by measurement: normalize-openapi --include-pattern computes the include list and trims nothing. Against stripe/openapi spec3.json at 51610f5f (MIT, re-read from the upstream LICENSE), a 6-operation pattern writes 63,317,655 bytes holding all 612 operations (sha256 0ea3c37a0854ad2646a156404b1ef86cca57403855e3803cd4630601eb6fc7b2); --max-depth 0 still writes 6,070,551 bytes with all 612. So 'the packaged spec is the script's output, its printed sha256 in the README' and 'keep it small' (recipe 1: trim to the operations the app calls) cannot both hold with the script as it is. The live sandbox call is NOT MEASURED for both apps: no vendor credential held.",
      "tests": "head cf30e616: pnpm --filter @objectstack/connector-app-github test prints 'Validation passed', then 'Test Files 2 passed (2)' and 'Tests 10 passed (10)' (VERDICT command-exit 0); pnpm --filter @objectstack/connector-app-github typecheck exits 0. boot.test.ts (bootStack, MCP client swapped by plugin name through extraPlugins, no vendor call) asserts: with no credential, github_mcp is degraded, its reason names GITHUB_MCP_TOKEN, and nothing is dialled; a flow run then answers 400 FLOW_FAILED naming the ref; PUT credential-refs/GITHUB_MCP_TOKEN brings it to ready with actions exactly [issue_read, search_issues] although the fake server also lists issue_write; the transport dialled carries GitHub's URL, X-MCP-Readonly true and Authorization Bearer plus the fixture token; both flows dispatch their tool with their inputs. listing.test.ts asserts: TemplateManifestSchema parses; manifestId equals stack manifest.id; no publisher/isStarter key; the README Credentials section names every declared credentialRef; no secret in any connector. Three one-off probes, not committed, on a fake server listing only get_me (classic-PAT scope filtering): (1) with the env var credential, the whole boot is refused ('Plugin com.objectstack.service-automation failed to start ... providerConfig.include names search_issues, issue_read, which the MCP server does not list'); (2) with the store credential, PUT answers 200 with state degraded and the log says 'a configuration fault ... Fix its declaration'; (3) a second PUT with a well-scoped value returns it to ready with no restart. No ablation: no tested behaviour of existing code changed (new package only).",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack, derived at cf30e616: 60 commands (48 by path, 6 by kind, 8 whole-tree). All 60 ran with the exit captured before any pipe, all exit 0. --ran reconciliation: '60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN' (a derived zero, all codes recorded). On the first run (head fbb7b6a2), check:test-source-alias and check:registry-log-declared were red on the new package's test setup; source aliases and OS_REGISTRY_LOG warn were added in cf30e616 and both are green ([Registry] lines in the suite 247 to 0). On that first run check:dual-build-cjs-loads was exit 3 PREREQUISITE NOT MET (sibling dists missing); on the final run it measured: 113 entry points, 70 packages load. No derived gate assumes a published platform app: check:published-files and check:changeset-fixed pass with the package private. CI on PR #28306 head cf30e616 at report time: 10 check-runs completed with no failure, 17 in_progress (not awaited). Not run locally, by rule: test:repo, pnpm lint and the other repo-wide scans (CI).",
      "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "1: mcp__claude-code-remote__add_repo (stripe/openapi, read; answered read_available, nothing attached). 0 GitHub MCP calls, 0 MCP writes.",
      "api_writes": "2 relay strokes, each POST /repos/objectstack-ai/objectstack/dispatches: (1) pr_create, which the relay executed as POST /repos/objectstack-ai/objectstack/pulls (draft) plus POST /repos/objectstack-ai/objectstack/issues/28306/labels [skip-changeset]; read-back identical, 7895 bytes, no assignees, labels [skip-changeset]; (2) this os-dev-report comment via post-stamped.mjs, POST /repos/objectstack-ai/objectstack/issues/28276/comments. git pushes (not REST): 4, one empty branch probe and three commits.",
      "files_changed": "11 files, +568/-0 vs base 69ce01d7, all inside the claimed surface: packages/apps/connector-github/{README.md, objectstack.config.ts, objectstack.manifest.json, package.json, src/connectors/github.connector.ts, src/flows/github.flows.ts, test/boot.test.ts, test/listing.test.ts, tsconfig.json, vitest.config.ts} and pnpm-lock.yaml (pnpm install). packages/apps/connector-stripe/** is absent from the branch.",
      "line_budget": "568 changed lines, under the 3000 human-merge threshold (dispatch-gates count). No skills/** file touched.",
      "deviations": [
        "PR first line is 'Part of #28276', not the dispatch's 'Fixes #28276': the Stripe half is pending a decision, and os-dev forbids a closing keyword on a card that still waits on a decision. The GitHub half alone does not complete the card.",
        "skip-changeset was declared in the pr_create labels. The dispatch says the PM sets it; os-dev.md (which wins on conflict) says the dev declares it in the same pr_create stroke when nothing published moves. Here the only new package is private, and nothing in any files[] changed.",
        "The PM's suggested route of one PR with two packages was not taken: the Stripe package was written, cannot be packaged as the card and recipe 1 prescribe, and was taken back off the branch (lockfile regenerated without it).",
        "Commit trailers are the model-free pair from AGENTS.md (Claude-Session plus Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By. The PR footer uses AGENTS.md's session-URL form."
      ],
      "open_questions": [
        {
          "question": "Stripe half: normalize-openapi cannot trim a vendor document to the included operations. How should the Stripe app's packaged OpenAPI document be produced so it is both the script's output (with its printed sha256 recorded in the README, per the card and #27293's Done-when) and small (recipe 1: trim to the operations the app calls)?",
          "options": [
            "A. Add a trim mode to scripts/normalize-openapi.mts in connector-openapi: keep only the operations the --include-pattern matches before hashing, then the Stripe app commits that output and its printed sha256. Measured size of the 6 included operations at max-depth 2: about 1.1 MB of the about 36 MB of operation content. Cost: one small change to that script plus its test (the connector-openapi lane, outside this card's file surface), then the Stripe package (about 600 lines plus the document) here. Effort: about 2 small PRs.",
            "B. Commit the full normalized output and rely on providerConfig.include: 63,317,655 bytes at the default max-depth 2, or 6,070,551 bytes at max-depth 0 (whose response schemas become stubs). Cost: over GitHub's 50 MB single-file warning at depth 2; every boot reads and parses it; the PR exceeds 3000 changed lines (maintainer-landing class); 606 dead operations shipped forever. No code change.",
            "C. Trim after normalizing (a hand step or an ad-hoc script) and record both hashes, the script's and the committed file's. Cost: the provenance is no longer one reproducible command, the card's 'output of the script' and 'the sha256 the script printed' are bent, and the next OpenAPI app author improvises a trimmer again. No tooling change."
          ],
          "recommendation": "A. Business need: the epic's Done-when needs provenance (upstream, commit, sha256), and every large vendor document on the shelf (Stripe: 612 operations) hits this, measured. Long term: one offline tool stays the single producer of the packaged bytes and their hash; C is a workaround and B ships dead weight. Stops AI mistakes: with A, the one command is the artifact; C invites each AI author to write its own trimmer with an unverifiable hash. Scope: A is one narrow flag on an existing tool with no new gate, and recipe 1 then matches the tool."
        },
        {
          "question": "Listing identity before the first publish: the package id is app.objectstack.connector-github (manifest.id equals manifestId, after HotCRM's app.objectstack.hotcrm), namespace github, npm name @objectstack/connector-app-github. The npm name is kept off @objectstack/connector-github because @objectstack/connector-* names the executor packages. The manifestId is immutable once published. Confirm the convention for the shelf, or name another.",
          "options": [
            "A. Keep app.objectstack.connector-VENDOR, namespace VENDOR",
            "B. Another convention, to be named before any publish"
          ],
          "recommendation": "A, because nothing has been published yet and the convention matches the one existing official listing (HotCRM). Cost of changing it later is zero until the first publish."
        }
      ],
      "out_of_scope_findings": [
        "class: a · reach: public door, PUT /api/v1/automation/connectors/credential-refs/GITHUB_MCP_TOKEN answers state degraded and the log prescribes 'a configuration fault ... Fix its declaration' when the credential is under-scoped and the declaration is correct; with the same credential in the env var, the whole boot is refused ('Plugin com.objectstack.service-automation failed to start'). Named real producer: GitHub's remote MCP server hides tools a classic PAT's scopes do not cover (github/github-mcp-server docs/scope-filtering.md at f2a07cd1). · evidence: three bootStack probes against a fake server listing only get_me (tests field); a second PUT with a good value recovers. Seam: runtime:packages/connectors/connector-mcp/src/mcp-provider.ts include-unknown refusal (plain Error, configuration class) into the service-automation materializer's configuration-fault policy (fatal at boot, no retry on reload); the credential-rejected class (401/403) degrades instead. · dedupe words: mcp include refusal, scope-filtered tools/list, classic PAT hidden tools, credential fault classified configuration, fix its declaration",
        "carrier: #28276 (open_questions[0]) · normalize-openapi --include-pattern trims nothing (63,317,655 bytes, 612 operations for 6 included), while recipe 1 in skills/objectstack-automation/references/integration-recipes.md teaches 'Trim the vendor's OpenAPI 3.x document to the operations the app calls'. Noted, not filed: the decision above carries it.",
        "carrier: none · check:template-manifests walks only packages/create-objectstack/src/templates, so this package's objectstack.manifest.json is parsed by its own listing.test.ts instead. Observation, not filed (in PR acceptance notes).",
        "carrier: none · content/docs/deployment/marketplace-handbook.mdx, README section: 'An app that ships declarative connectors gains an offline spec-normalization tool with #26709' still reads as future although the tool (normalize-openapi) has landed. Docs drift, not filed; it is not in the PR acceptance notes and the seat may add it there."
      ]
    }
  4. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U

    Dev report received · dispositions · 2026-10-31T04:14Z

  5. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U

    Release: claim 6538171907 (session_017xRBcVBKAFk1ntXSjvPt7U, epic:#27293#1) · partial landing · 2026-10-31T05:12Z
    Blocked-by: #28309

    reading value
    landed the GitHub app: PR #28306 merged through the queue, merge commit 7a0481a8f (Part of #28276, no closing keyword)
    remaining the Stripe app (read only, OpenAPI), waiting on #28309 (the normalizer's trim mode, in flight)
    state pm:dispatched → pm:blocked in this act; assignee cleared; pm:epic stays — the epic PM re-claims the Stripe half with the full claim protocol when #28309 closes
    owed elsewhere #28313 (listing identity, needs-user-decision) before the first publish; #28311 (under-scoped token) updates packages/apps/connector-github/README.md
  6. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U

    Claim: PM loop round 3 (the Stripe half; the GitHub half landed in PR #28306, Release 6539426544)
    Session: session_017xRBcVBKAFk1ntXSjvPt7U
    Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-28276-connector-app-stripe
    Worktree: objectstack-issue-28276
    Domain: domain:server
    Seat: epic:#27293#1
    File surface: packages/apps/connector-stripe/** (new npm-private metadata package under the existing packages/apps/* glob, laid out like packages/apps/connector-github), pnpm-lock.yaml (regenerated by pnpm install, never by hand) (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus (TIER_DEFAULT — no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6539426544
    Ruling-ref: 6486157794
    Premise: holds (read at origin/main 64c56685 2026-10-31T05:56Z: normalize-openapi --trim landed in PR #28331, so the packaged document can be the script's trimmed output with its printed sha256; packages/apps/connector-github is on main as the layout reference; pm:blocked → pm:dispatched in this act because Blocked-by: #28309 closed)
    Serial constraints cleared: none — none of the 60 most recent open PRs touches packages/apps/connector-* or pnpm-workspace.yaml; #28311 (in flight) may edit packages/apps/connector-github/**, a sibling directory — disjoint, the lockfile alone may conflict and the later lander regenerates it.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions