You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit e63f6ec
Browse filesBrowse the repository at this point in the historyBrowse files
docs(skills): objectstack-data teaches membership keys, ownerMayEdit, create-only seed columns, the position-to-set binding and the external tier
rules/security.md: a membership-keys section (declare `membershipKeys` on
the roster object; the three members; the refusals; the once-per-request
fail-closed read; the choice rule against owner scoping, a position and a
sharing rule), then the position -> `permissionSets` binding (a namesake
set is reported, never granted) and the `external` membership tier for
portal users (no baseline, explicit grants only).
rules/relationships.md: `sharing.controlledByParent.ownerMayEdit` beside
the controlled_by_parent row.
references/seeds.md: the `columns` dataset key and `applyOn: 'create'`.
references/examples-objects.md: the two `{ type: 'lookup', reference:
'user' }` fields become `type: 'user'`.
evals: one portal membership case; the seed and invoice-line cases gain
the new keys.
scripts/check-skills-token-ratchet.mjs: the six touched objectstack-data
rows follow the measurement (five raised under the maintainer's ruling,
one lowered by the net cut).
Claude-Session: https://claude.ai/code/session_01JQwxbXTWvHG6MXFD7Gywf2
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: skills/objectstack-data/evals/hooks-security-seeds-datasources.json
+13-3Lines changed: 13 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -33,11 +33,11 @@
33
33
},
34
34
{
35
35
"id": 4,
36
-
"prompt": "Seed the `country` reference table for every environment, and add demo `opportunity` rows (dev/test only) that close 45 days after install and are owned by whoever installs the package.",
37
-
"expected_output": "Uses `defineSeed(Country, { externalId: 'code', mode: 'upsert', records })` for reference data and `defineSeed(Opportunity, { env: ['dev', 'test'], ... })` for demo rows, with lookups referenced by natural key and dynamic values as CEL: `close_date: cel`daysFromNow(45)``, `owner_id: cel`os.user.id``. Never `externalId: 'id'`, never `new Date()` / `Date.now()` (breaks build determinism), never `defineDataset` (the analytics layer), parents before children in the exported array.",
36
+
"prompt": "Seed the `country` reference table for every environment, and add demo `opportunity` rows (dev/test only) that close 45 days after install and are owned by whoever installs the package. A nightly job advances each opportunity's `stage`; replaying the seed must not reset it.",
37
+
"expected_output": "Uses `defineSeed(Country, { externalId: 'code', mode: 'upsert', records })` for reference data and `defineSeed(Opportunity, { env: ['dev', 'test'], ... })` for demo rows, with lookups referenced by natural key and dynamic values as CEL: `close_date: cel`daysFromNow(45)``, `owner_id: cel`os.user.id``. Never `externalId: 'id'`, never `new Date()` / `Date.now()` (breaks build determinism), never `defineDataset` (the analytics layer), parents before children in the exported array. The job-owned column is declared `columns: { stage: { applyOn: 'create' } }`, so an `upsert` replay leaves it as the row holds it.",
"prompt": "Customers' staff sign in to our portal and may read only the orders of the accounts they belong to; staff of one account must never see another account's orders.",
57
+
"expected_output": "Declares the set on the roster object that defines it: `account_member` (`user` field + `account` lookup) with `membershipKeys: { portal_account_ids: { userField: 'user', valueField: 'account' } }`; a portal permission set whose `rowLevelSecurity` reads it (`using: 'account in current_user.portal_account_ids'`), distributed by a position naming it in `permissionSets`; portal staff are invited on the `external` membership tier, outside the `everyone` baseline. Never a policy per account, never an owner stamp on every order.",
Copy file name to clipboardExpand all lines: skills/objectstack-data/evals/objects-fields-relationships.json
+4-4Lines changed: 4 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -13,12 +13,12 @@
13
13
},
14
14
{
15
15
"id": 2,
16
-
"prompt": "Model invoices with line items, and let invoices be tagged with many tags where each tagging records who added it and when.",
17
-
"expected_output": "Line items: `invoice_line` with a `master_detail` field to `invoice`, `required: true`, `deleteBehavior: 'cascade'` (or `'restrict'` — `set_null` is refused on master_detail), `inlineEdit` on that relationship, and a `summary` roll-up field on the parent. Tagging carries attributes, so it is a junction object (`invoice_tag`) with two `lookup` fields plus `added_by` / `added_at` — not a `multiple: true` lookup (an array of ids) and not a `many_to_many` type, which does not exist.",
16
+
"prompt": "Model invoices with line items, and let invoices be tagged with many tags where each tagging records who added it and when. A rep who owns a line item but can only read the invoice may still correct that line.",
17
+
"expected_output": "Line items: `invoice_line` with a `master_detail` field to `invoice`, `required: true`, `deleteBehavior: 'cascade'` (or `'restrict'` — `set_null` is refused on master_detail), `inlineEdit` on that relationship, and a `summary` roll-up field on the parent. Tagging carries attributes, so it is a junction object (`invoice_tag`) with two `lookup` fields plus `added_by` / `added_at` — not a `multiple: true` lookup (an array of ids) and not a `many_to_many` type, which does not exist. The line object is `sharingModel: 'controlled_by_parent'` with `sharing: { controlledByParent: { ownerMayEdit: true } }` (by-id update only; every other write still needs master edit). `added_by` is `type: 'user'` — never a `lookup` to a `user` object, which does not exist.",
|`lookup`| Independent | Optional by default | Independent | Supported via `summary`| "Related to" |
16
-
|`master_detail`| Coupled (cascade delete) | Forced only under `controlled_by_parent`; else lint-warned | Inherits parent | Supported via `summary`| "Owned by" |
16
+
|`master_detail`| Coupled (cascade delete) | Forced only under `controlled_by_parent`; else lint-warned | Inherits parent; owner opt-in `ownerMayEdit` (below)| Supported via `summary`| "Owned by" |
17
17
|`tree`| Self-reference | Optional — and so is `reference`, which when written must name this object itself; any other object is refused at parse, not lint-warned | N/A | Not available | Hierarchical |
0 commit comments