Skip to content

skills(objectstack-data): teach an object extension's fieldPatches in the Object Extension Model section, once #28565 applies them #28730

Closed

Description

@objectstack-fleet

domain:server#5 · os-project-manager · session_01FEkQ5oc56xChD6Wrc4cGSt

Filing gate: ③ the Skills-docs: follow-up owed line of PR #28728 (#28565), filed by the seat before ACCEPT as the review checklist requires. ⛔ Not a claim. Graded by this seat: p3 (documentation of a live key; the spec .describe() and content/docs/data-modeling/object-extensions.mdx already teach it), under 「定级你可以自己决定」 (Leehom, 2026-11-01).
Reach: an AI author working from the objectstack-data skill who wants a vendor field to read "Sector" instead of "Industry" learns only fields / priority, so it redeclares the field in fields (taking it over) instead of patching its display.

Wanted

  • skills/objectstack-data/SKILL.md, section "Object Extension Model": one short paragraph on fieldPatches — display keys only (BASE_FIELD_DISPLAY_WHITELIST: label, description, inlineHelpText, placeholder, option labels by stored value); type, values and rules stay the owner's; tenant edits win, higher priority wins between extensions; a patch naming a missing field or option is refused at install and by os validate; a picklist-bound field's options are not patchable. One example, the crm_account.industry one from the changeset.
  • Lands after PR feat(objectql): an object extension's fieldPatches relabels the vendor field on every read, refused at install and os validate when it names nothing (#28565) #28728 merges (the key is [EXPERIMENTAL — not enforced] on main until then). Governed path (skills/**): Tier H; publishes via @objectstack/skills.

Links back: #28565, PR #28728.

Blocked-by: #28565

Activity

  1. added
    documentationImprovements or additions to documentation
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Nov 1, 2026
  2. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-project-manager · session_01FEkQ5oc56xChD6Wrc4cGSt

    Unblocked · pm:queue

    ⛔ Not a claim.

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

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    Claim: PM loop round 1
    Session: session_017ihL2g7RyXa8ErM6GAkHyc
    Account: marchtian
    Branch: claude/issue-28730-field-patches-skill
    Worktree: objectstack-issue-28730
    Domain: domain:skills
    Seat: domain:skills#2
    File surface: skills/objectstack-data/SKILL.md 〈Object Extension Model〉 only, plus the changeset the published skill package owes.
    Container & model: M, mode:subagent, model: claude-fable-5-1 (dispatch-gates --tier: MANDATORY on skills/**, clause ①, no one-line exit), effort: high; then an independent CONTRACT_REVIEW_TIER review by a separate agent.
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (the Skills-docs: follow-up owed line of PR #28728)
    Thread-read: 6561922000
    Premise: holds. Blocked-by: #28565 is closed by PR #28728 (e62dcc567b), so ObjectExtensionSchema.fieldPatches is live on main. skills/objectstack-data/SKILL.md 〈Object Extension Model〉 (L373 on main) does not mention fieldPatches.
    Serial constraints cleared: no open PR touches skills/objectstack-data/** (read over every open PR).
    Landing: Tier H (skills/**) per the card; the stricter path applies as for this seat's other cards. The PR stays draft with needs-user-decision until an authorised approver acts.

  5. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-project-manager · session_01FEkQ5px88TLYX7Piuoxnb2

    For the fieldPatches paragraph this card asks for: once PR #28791 lands, a field patch reaches the owner's own fields only, so a patch naming a field another extension adds (or one the same extension adds in fields) is refused at install and by os validate, and is not applied at boot; teach "set that field's text where it is declared".


    Generated by Claude Code

  6. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    os-dev-report

    {
      "issue": 28730,
      "status": "done",
      "branch": "claude/issue-28730-field-patches-skill",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28795",
      "head": "7ba013288b8216e40ea3eeaacb9066f691f399b8",
      "session": "session_017ihL2g7RyXa8ErM6GAkHyc",
      "premise_still_valid": true,
      "summary": "skills/objectstack-data/SKILL.md section Object Extension Model gains one paragraph on fieldPatches: relabel a vendor field with it instead of redeclaring the field in fields (which takes the field over); display keys only per BASE_FIELD_DISPLAY_WHITELIST (label, description, inlineHelpText, placeholder, an option's label keyed by its stored value); type, values and rules stay the owner's; a tenant's edit wins; the higher priority wins between extensions; a patch naming a missing field or option value is refused at install and by os validate; a picklist-bound field's options are never patchable; with the crm_account.industry example from .changeset/28565-field-patch-applied.md. Paid under the token ratchet by deleting restatement in the same file. One patch changeset for @objectstack/skills (the skill ships in packages/skills dist, synced from skills/**). Every claim read off the live code at merge base b48eeb16c4, cited under facts. PR #28795 is draft, no labels, no assignees, no reviewers; Tier H (skills/**) awaits an authorised approval.",
      "tests": "docs-only diff: no package test suite reads skills/**; no ablation (no tested behaviour changed). The derived gates under gates are the measurement. Extra, not derived: pnpm --filter @objectstack/spec run check:skill-refs — 9 generated files in sync with packages/spec, exit 0.",
      "gates": "Local subset at head 7ba013288b (tree clean throughout): node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 45 commands (34 before the changeset existed, 11 more after; both derivations run). Each run with its exit code captured before any pipe (cmd > log 2>&1; status=$?). --ran verdict: 45 derived, 45 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. First pass before the whole-repo build: pnpm --filter @objectstack/lint run check:doc-formula-expressions exit 3, pnpm check:dual-build-cjs-loads exit 3, pnpm check:lean-entry-closure exit 3 (PREREQUISITE NOT MET: built output missing), pnpm check:dts-closure exit 1 (@objectstack/lint declaration files missing; its dts build needs @objectstack/sdui-parser built first); after pnpm build under os-verify-lock.sh (Tasks: 117 successful, 117 total; VERDICT command-exit 0; held 13m57s) each exit 0. The other 41 exit 0 on first run, among them: node scripts/check-skills-token-ratchet.mjs (skills/objectstack-data/SKILL.md is 6111 tokens (ceiling 6123; headroom 12); 57 authored bundle file(s) within their ceilings) and its --self-test; pnpm check:skill-frame-sync; check:skill-compatibility; check:skill-identifier-liveness; check:pm-skill-id-lint; check:role-word; check:doc-authoring; check:nul-bytes; check:pm-governed-merges; pnpm --filter @objectstack/spec run check:skill-docs; node scripts/check-adr-0087-registration.mjs --base origin/main; check-changeset-no-major; check-empty-changeset; pnpm check:changeset-gate-self-tests; check:pm-changeset-deadline-census; check:published-files; check:closed-ceremony-text; check:merge-driver; check:gitlink-declared; check:cross-package-test-inputs; check:corpus-claim-drift; check:ci-filter-parity; check:agent-test-spelling; check:driver-memory-census; check:refd-timer-probe; check:sourcemap-no-sources-content; check:watch-hint-literal; check-closing-keyword-parity; check-comment-mask-corpus; check-doc-route-spelling --advisory; check-dts-emitted --self-test; ci/* self-tests; release-rehearsal-clone --self-test; release-pending-publish --self-test. Not run locally, CI's: check:skill-examples (not derived; no fenced TypeScript block added), test:repo. Local-only families check:dev-prereqs / check:skill-frame-freshness not run: the diff touches neither packages/spec nor a frame file. CI check-runs on the PR head at report time: 36 check-runs read at 7ba013288b right after the create — completed/success: Lint · PM dispatch-gates, Governed Surface Queue Guard, PR-body guards, Check PR Size, Auto Label, filter, Test UI, Dogfood Regression Gate; in_progress: Lint · CI release & engine gates, Lint · ESLint, Lint · repo & tooling gates, Lint · docs & code guards, Lint · scoped (tooling self-tests, slot lookup & corpus, query-options erasure), Type Check (workspace, source gates, consumer gates, debt ledger), Build Core, Plan Test Core shards, Check Changeset, Live E2E UI; skipped (paths): Type Check UI, Lint UI, Build & E2E UI, Build UI Deps, Build Docs, UI Published Artifacts, Test UI shards, Dogfood shards/Verify CLI, Temporal Conformance, the opt-in harnesses. Not awaited (os-dev contract: no CI wait).",
      "line_budget": "skills/objectstack-data/SKILL.md: 472 -> 468 lines; 6101 -> 6111 tokens against ceiling 6123 (headroom 22 -> 12), ratchet convention ceil(bytes/4) minus the stamp line. Package, all skills/*/SKILL.md: 4561 -> 4557 lines; 56328 -> 56337 tokens (ceil(bytes/4), stamp lines included). No ceiling moved. Paid by deleting restatement in the same file: Search Fields L171-176 (restated L122-129; the searchable-field-unknown code folded into L125), Index Patterns blockquote L360-364 (carried by rules/indexing.md L26-34 and L63-77; the pointer sentence now names the retired keys and the scope words), Validation Patterns list L331-337 (carried by rules/validation.md L16-22; the six names kept on one line). The standing ruling 2026-10-27 is quoted in the PR body for the record; nothing here needed a raise.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "0 — no MCP GitHub tool was called; reads went through gh api (REST) and the relay's own read-back",
      "api_writes": "2 relay strokes, both POST /repos/objectstack-ai/objectstack/dispatches executed by the fleet-write run as objectstack-fleet[bot]: (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (run 41345584390, conclusion success, read-back 9656 bytes sent / 9656 stored, identical); (2) this comment -> POST /repos/objectstack-ai/objectstack/issues/28730/comments via post-stamped.mjs. git push is not a REST write. No labels sent: the dispatch named none and a changeset exists, so skip-changeset does not apply.",
      "deviations": [
        "The pr_create relay call was run detached (nohup, waited on with tail --pid) rather than under `timeout 110`, so its own read-back could complete; its exit code was not captured by the waiting shell (the `&` list swallowed it) — the evidence is its log's read-back line (identical bytes) and an independent gh api read of the PR (28795, draft, head 7ba013288b, no labels, no assignees).",
        "pnpm install --frozen-lockfile and the builds (spec+formula+lint, then the whole repo) were prerequisites; the first lint build attempt was invoked with --concurrency=2 after --filter, which pnpm forwarded to the build script and the lint dts build failed on the unbuilt @objectstack/sdui-parser — superseded by the whole-repo build, no file changed.",
        "No details/summary blocks in the PR body: angle-bracket discipline for GitHub text took precedence over the log-folding form; readings are plain bullets.",
        "The worktree /home/claude/objectstack-issue-28730 and its node_modules are left in place for the seat's patch rounds on this Tier H PR; the seat removes it."
      ],
      "files_changed": [
        "skills/objectstack-data/SKILL.md",
        ".changeset/28730-skill-field-patches.md"
      ],
      "facts": [
        "patchable keys = label, description, inlineHelpText, placeholder; option key = label: packages/spec/src/data/field-customization.ts:75-80 (BASE_FIELD_DISPLAY_WHITELIST.field L77, .option L79); the slot's .describe(): packages/spec/src/data/object.zod.ts:4958-4967",
        "options matched by stored value: packages/objectql/src/registry.ts:585-587 (hasOwnProperty(optionPatches, option.value)); packages/metadata-core/src/extension-field-patch-targets.ts:130-136 ('an option is addressed by its stored value')",
        "type, values and rules stay the owner's: packages/spec/src/data/field-customization.ts:65-68; packages/spec/src/data/object.zod.ts:4960-4962",
        "tenant edits win: packages/objectql/src/registry.ts:576 and :592 (tenantPatched yield in patchedField), :731-734 (mergeObjectDefinitions comment, ADR-0029 D9.2a)",
        "higher priority wins between extensions: packages/objectql/src/registry.ts:4202-4203 (contributors.sort ascending by priority), :735-736 (the higher one is written last)",
        "missing field or option refused at install and by os validate: packages/metadata-core/src/extension-field-patch-targets.ts:95-103 (reason field) and :126-137 (reason option); packages/cloud-connection/src/marketplace-install-local-plugin.ts:2136-2146 (400 VALIDATION_ERROR, details.refusals); packages/cli/src/commands/validate.ts:732-745",
        "picklist-bound field's options not patchable: packages/metadata-core/src/extension-field-patch-targets.ts:112-124 (reason picklist-option); packages/objectql/src/registry.ts:581-582 (picklistBound skips options)",
        "redeclaring the field in fields takes it over: packages/objectql/src/registry.ts:701-703 (merged.fields = { ...base.fields, ...extension.fields }); content/docs/data-modeling/object-extensions.mdx:96-100",
        "the example: .changeset/28565-field-patch-applied.md L13-18 and content/docs/data-modeling/object-extensions.mdx:101-114 (crm_account.industry, label Sector, options.tech.label Technology)"
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: #28730's seat · noted, not filed — the objectstack-data evals do not exercise object extensions (git grep objectExtensions skills/objectstack-data/evals: none); an eval fixture is outside the token ratchet (ruling record 6513306068 letter B), so one could be added without paying; not in this card's Wanted."
      ]
    }
  7. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    os-dev-report

    Patch round on PR #28795 — the two should-fixes of contract review 6563471541 applied; delta against report 6563288115.

    {
      "issue": 28730,
      "status": "done",
      "branch": "claude/issue-28730-field-patches-skill",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28795",
      "head": "cbd8528c5b64fcdf46d8a1a84f261bc419c12b5f",
      "previous_head": "7ba013288b8216e40ea3eeaacb9066f691f399b8",
      "session": "session_017ihL2g7RyXa8ErM6GAkHyc",
      "premise_still_valid": true,
      "summary": "Two edits in skills/objectstack-data/SKILL.md, section Object Extension Model: (1) the example's option key is now a stored value the reference CRM declares — options: { technology: { label: 'Tech' } } — after confirming examples/app-crm/src/objects/account.object.ts on origin/main (crm_account.industry, inline options technology / finance / healthcare / retail / other, no picklist binding); the former key tech named no option there and was refused at os validate and install with reason option; (2) the section's spelled signature reads defineObjectExtension({ extend, fields, fieldPatches, priority }). No other file changed; the changeset stands as written.",
      "files_changed": [
        "skills/objectstack-data/SKILL.md"
      ],
      "line_budget": "skills/objectstack-data/SKILL.md: 468 lines unchanged; 6111 -> 6114 tokens against ceiling 6123 (headroom 12 -> 9); the option rename is byte-neutral (tech->technology +6, 'Technology'->'Tech' -6), the signature's fieldPatches costs the 3. Package total +3 tokens. No ceiling moved. Ratchet: 57 authored bundle file(s) within their ceilings, exit 0.",
      "gates": "At head cbd8528c5b (tree clean): node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived the same 45 commands as round 1; each run with its exit code captured before any pipe; all 45 exit 0 on first run (the built tree from round 1 still in place); --ran verdict: 45 derived, 45 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. Among them node scripts/check-skills-token-ratchet.mjs (6114 tokens, headroom 9) and its --self-test, pnpm check:skill-frame-sync, check:skill-compatibility, check:skill-identifier-liveness, check:pm-skill-id-lint, check:role-word, check:doc-authoring, check:nul-bytes, pnpm --filter @objectstack/spec run check:skill-docs, the changeset family. CI check-runs on the new head: not awaited (os-dev contract).",
      "tests": "docs-only; no package test reads skills/**; no ablation.",
      "mcp_calls": "0",
      "api_writes": "1 relay stroke for this round: POST /repos/objectstack-ai/objectstack/dispatches -> POST /repos/objectstack-ai/objectstack/issues/28730/comments (this comment, via post-stamped.mjs). git push is not a REST write. PR body not re-sent (dev writes it once).",
      "deviations": [],
      "read_only_answer": "content/docs/data-modeling/object-extensions.mdx L113 (options: { tech: { label: 'Technology' } }) and .changeset/28565-field-patch-applied.md L20 carry the same non-existent tech key, as does the slot's own .describe() and TSDoc example in packages/spec/src/data/object.zod.ts (L4838, L4882, L4966 on origin/main 0aaad18fc0). Read only; none edited — the mdx and the changeset are outside this card's file surface, and a .describe() edit would owe a spec regeneration.",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: c (metadata-authoring trap) · reach: content/docs/data-modeling/object-extensions.mdx L113 and the fieldPatches .describe() in packages/spec/src/data/object.zod.ts teach options: { tech: ... } against crm_account.industry, whose reference options store technology; an author copying either is refused at os validate / install with reason option (loud, listing the real values). carrier: #28730's seat — noted, not filed; dedupe words: fieldPatches tech technology object-extensions describe"
      ]
    }
  8. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    ACCEPT → PR #28795 comment 6563719953 (head cbd8528c5b64fcdf46d8a1a84f261bc419c12b5f; contract review PASS 6563471541 → patch round 6563616611 → delta PASS 6563706246). The PR is a draft with needs-user-decision, and os-zhuang and hotlong are requested as reviewers; it waits on an authorised approver. Out of scope, filed: #28803 (the tech example key in spec and docs) and #28804 (an eval for object extensions).

  9. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    Landed 2026-11-02T00:14Z: PR #28795 merged as 00918c886c (merge queue; readied and enqueued by os-zhuang). Seat ACCEPT 6563719953. Filing #28804 (an objectstack-data eval for object extensions) named this card as its blocker; it is now unblocked and still awaits triage.

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

Metadata

Metadata

Assignees

Labels

area:datadocumentationImprovements or additions to documentationdomain:skillsDomain lane — seat card indexed by label:pm:seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions