Raised by card 08 (#18, seed data), by Claude Code session session_01KcrVDXSptwDukFsHPHPR1V, rather than editing the governed surface.
The conflict
- §03 declares the field as
our_entity select(签约主体,种子) — the parenthetical says the value list is seed data.
- §10 asks the demo to be "一家虚构的跨国集团(美国母公司,欧洲与亚太子公司)" — a US parent with European and Asia-Pacific subsidiaries, which only means something if a contract can say which entity signed it.
src/objects/contract.object.ts implements it as a select with exactly one option, head_office, and a comment saying a group with several legal entities replaces the list with its own: "The shipped list is a single placeholder — a group with several legal entities replaces it with its own (DESIGN.md §01: signing entities are configuration, not schema)."
A select's options are schema. A seed writes values, and the value vocabulary is closed.
Measured (@objectstack/* 17.3.0), both write paths
Through the REST API, as the platform admin:
POST /api/v1/data/clm_contract {"our_entity":"meridian_holdings_us", ...}
-> HTTP 400
{"error":"Our Signing Entity must be one of: head_office","code":"VALIDATION_FAILED",
"fields":[{"field":"our_entity","code":"invalid_option","options":["head_office"]}]}
Through the seed loader, which is a system write and bypasses RBAC:
✗ Failed to write clm_contract record #0 (title=PROBE entity vocab):
Our Signing Entity must be one of: head_office
Positive control: the other 14 rows of the same seed load inserted without complaint, so the refusal is about the value and not about the seed path. isSystem bypasses RBAC; it does not widen a select's vocabulary.
What card 08 did instead
#18 seeds our_entity: 'head_office' on all 120 contracts and expresses the multi-entity group through the axes that ARE data: governing law (US-NY 37 / Germany 38 / England and Wales 35), currency (USD 42 / EUR 41 / GBP 37), jurisdiction, and the counterparty base. That satisfies §10's observable requirements — three currencies, three governing laws — but the group's own signing entities are invisible, and "which of our entities signed this" is not answerable from the demo data.
Options
A. Leave it. The demo shows a multi-jurisdiction book signed by one entity. Honest, and the placeholder comment already says a customer replaces the list. Cost: §03's "(种子)" stays untrue for this field, and the §10 story is thinner than the table promises.
B. Ship three options (head_office, plus an EU and an APAC entity) in contract.object.ts and let the seed spread contracts across them. Cheapest thing that makes §10 true. Cost: an edit to a card-02 file and, arguably, to §01's rule that signing entities are configuration rather than schema — three placeholder entities in the shipped product is still schema, just three of them.
C. Make the signing entity a lookup to a real object (a clm_entity, or the platform's sys_business_unit), so the list genuinely is data and a seed can extend it. This is what "(种子)" describes. Cost: a §03 change, a new object or a platform-object dependency, and a migration for anyone already on our_entity.
Recommendation: B if the demo matters more, C if §03's word matters more. B is one field edit and makes the seed table honest today. C is the shape §03 actually describes and the one a group with a real entity list needs, but it is a governed-surface decision with a migration behind it. Either way, this is not card 08's to take.
Raised by card 08 (#18, seed data), by Claude Code session
session_01KcrVDXSptwDukFsHPHPR1V, rather than editing the governed surface.The conflict
our_entity select(签约主体,种子)— the parenthetical says the value list is seed data.src/objects/contract.object.tsimplements it as aselectwith exactly one option,head_office, and a comment saying a group with several legal entities replaces the list with its own: "The shipped list is a single placeholder — a group with several legal entities replaces it with its own (DESIGN.md §01: signing entities are configuration, not schema)."A
select's options are schema. A seed writes values, and the value vocabulary is closed.Measured (
@objectstack/*17.3.0), both write pathsThrough the REST API, as the platform admin:
Through the seed loader, which is a system write and bypasses RBAC:
Positive control: the other 14 rows of the same seed load inserted without complaint, so the refusal is about the value and not about the seed path.
isSystembypasses RBAC; it does not widen a select's vocabulary.What card 08 did instead
#18 seeds
our_entity: 'head_office'on all 120 contracts and expresses the multi-entity group through the axes that ARE data: governing law (US-NY 37 / Germany 38 / England and Wales 35), currency (USD 42 / EUR 41 / GBP 37), jurisdiction, and the counterparty base. That satisfies §10's observable requirements — three currencies, three governing laws — but the group's own signing entities are invisible, and "which of our entities signed this" is not answerable from the demo data.Options
A. Leave it. The demo shows a multi-jurisdiction book signed by one entity. Honest, and the placeholder comment already says a customer replaces the list. Cost: §03's "(种子)" stays untrue for this field, and the §10 story is thinner than the table promises.
B. Ship three options (
head_office, plus an EU and an APAC entity) incontract.object.tsand let the seed spread contracts across them. Cheapest thing that makes §10 true. Cost: an edit to a card-02 file and, arguably, to §01's rule that signing entities are configuration rather than schema — three placeholder entities in the shipped product is still schema, just three of them.C. Make the signing entity a lookup to a real object (a
clm_entity, or the platform'ssys_business_unit), so the list genuinely is data and a seed can extend it. This is what "(种子)" describes. Cost: a §03 change, a new object or a platform-object dependency, and a migration for anyone already onour_entity.Recommendation: B if the demo matters more, C if §03's word matters more. B is one field edit and makes the seed table honest today. C is the shape §03 actually describes and the one a group with a real entity list needs, but it is a governed-surface decision with a migration behind it. Either way, this is not card 08's to take.