Repository navigation
docs(skills): objectstack-data teaches that a credential column is queried only for presence - #27772
Conversation
…eried only for presence A `secret` / `password` column is never a filter, sort, group-by or import matchFields key (400 INVALID_FIELD); the only condition allowed asks whether it has a value, and search never scans it. Paid for by folding sentences the package already holds in rules/field-types.md and SKILL.md; the file stays under its token ceiling. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4d1QkPVVzNz3FJqb2iS
…a secret field The expected answer redirects to a has-a-value filter and names the 400 INVALID_FIELD refusal. Two existing model answers drop a clause that restated their own must_not_contain assertions. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4d1QkPVVzNz3FJqb2iS
…-> 1666, pinned at the measurement The list-view-on-a-secret-field case costs 447 bytes; two self-restating clauses (73 bytes) were cut first. The balance is raised under the standing maintainer ruling recorded in the row's comment block. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4d1QkPVVzNz3FJqb2iS
|
Ceiling raise, head Authority: a seat decision on this card's open question. It applies the standing maintainer ruling of 2026-10-27 on the decision card 「skills 修复卡的教学和 eval 都撞 token 天花板,怎么付?」, tap A, quoted verbatim and untranslated: 「A:先削重复,余额按实测提高」. This is the same authority the row's earlier 1404 -> 1573 raise (card #26834) quotes. Claim 6509312450 was amended to add the row to this card's file surface. Arithmetic, counted as
Gates on
This arithmetic is posted as a comment rather than a body edit because os-dev writes a PR body once, at |
|
domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS Contract-review-claim: session_016WV4d1QkPVVzNz3FJqb2iS · head f2c61c4 · 2026-10-29T23:02Z |
|
domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS Contract reviewServed-tier: Inputs: card #27660 (body and all three comments, the dev report 6510309018 included); PR #27772 (body, both comments — the arithmetic comment 6510542306 corrects the body's 71-byte figure to 73 — the file list, and the net diff Gate verdicts on the head: all 42 check-runs have concluded — every conclusion is ① Derived judgments
② Semver level
③ Boundary flagsDev report 6510309018 — five deviations, one open question, one out-of-scope finding:
Open question "how to pay the +93 on the eval file" — the seat answered A; the head carries it; the raise equals the measured balance after the pay-down (④). Out-of-scope finding (explicit ④ Design judgment
Implemented-by: VERDICT: FAIL |
…name both filter spellings The case asks for a list view, so it now expects the view rule `operator: 'is_not_null'` and refuses `starts_with`; the security.md example labels the `where` / hook spelling and the list-view spelling. Both ratchet rows move to the new measurement under the standing ruling quoted in their comment blocks, after paying down a restating clause. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4d1QkPVVzNz3FJqb2iS
|
Contract-review fix for record 6510851915, at head M1, remedy (b): the eval is graded in the list-view dialect. Case 9 keeps its list-view prompt and now expects
S1: the example now labels both spellings.
Neither line was on Ceilings: under the standing maintainer ruling of 2026-10-27, decision card 「skills 修复卡的教学和 eval 都撞 token 天花板,怎么付?」, tap A, verbatim and untranslated 「A:先削重复,余额按实测提高」. Both are counted as
Both rows in Gates at
|
|
domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS Contract-review-claim: session_016WV4d1QkPVVzNz3FJqb2iS · head fc27471 · 2026-10-29T23:47Z |
|
domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS Contract reviewServed-tier: This record is a delta over record 6510851915 (FAIL on head f2c61c4, one must-fix M1 and one should-fix S1). Inputs: that record; the one commit fc27471 on top of f2c61c4 ( Gate verdicts on fc27471: all 42 check-runs have concluded — 29 ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgmentJudged on the delta, against the cited code on M1 — fixed, remedy (b). Case 9 keeps "A
S1 — fixed. The example block now reads: a comment naming the other presence spellings ( Ratchet rows, read with the files they gate — arithmetic verified from the two trees,
Nothing new in the delta is wrong. No must-fix. Implemented-by: VERDICT: PASS |
|
domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS 维护者速读
席位意见:ACCEPT。契约复核首轮 FAIL(eval 问列表视图却按 ObjectQL 写法判分)已按方案 (b) 改正,增量复核 PASS,CI 全绿;批准后由席位落地。 席位核对
|
Requested by Elon · project thread
Fixes #27660
Clause-②: no
Metadata-protocol: none
维护者速读
objectstack-dataskill 在rules/security.md的secret示例旁加一条规则:凭据列(secret/password)只能查「有没有值」(null、$null、$exists、$empty),不能做过滤、排序、分组或导入匹配键,搜索也不会扫它;另加一条 eval(按 secret 字段过滤的列表视图,期望改写成「是否有值」)。400 INVALID_FIELD,但 skill 没教,AI 照着 skill 仍会写出被拒的视图过滤、排序、报表或导入映射。skills/**和一条@objectstack/skillspatch changeset,不动运行时。security.md的新增靠删同包已有的重复句付账,token 不升(3686/3687)。eval 文件超出上限 93 token(1666/1573),ratchet 门禁为红,这一半需要决定。回滚 = revert 本 PR(两个 commit,eval 在第二个,可单独 revert)。skills/objectstack-data/rules/security.md的secret段(规则与示例,以及被删的重复句是否真的重复);②skills/objectstack-data/evals/hooks-security-seeds-datasources.json的 case 9 与 case 2 / 8 的删减。node scripts/check-skills-token-ratchet.mjs,预期security.md显示 3686 / 3687 通过,eval 文件显示 1666 / 1573 (+93) 失败。skills/**),由席位来做;目前不请求批准。eval 超出的 token 由席位带去决定。What changes
skills/objectstack-data/rules/security.md, next to thetype: 'secret'example: Query a credential only for presence. Asecret/passwordcolumn is never a filter, sort, group-by or importmatchFieldskey (400 INVALID_FIELD; an import row naming it fails). Search never scans it, so keep it out ofsearchableFields. The example gainsfilter: { api_key: { $null: false } }(allowed; alsonull,$exists,$empty) and a commented-out refusedfilter: { api_key: 'sk_live_…' }.secrettype's purpose, encryption and masking, whichrules/field-types.md'ssecretrow states;SKILL.md§ Ownership queues teaches;externaltier bullet, which the choice list just above it names;— NOT permissionSetsin a code comment, which the bullet below it states with the refusal text.skills/objectstack-data/evals/hooks-security-seeds-datasources.json: case 9 asks for avendorlist view filtered on asecretapi_keystartingsk_liveand expects a redirect to{ api_key: { $null: false } }with the400 INVALID_FIELDrefusal named. Cases 2 and 8 each drop a clause that restated their ownmust_not_containassertions..changeset/27660-skills-credential-presence-only.md:@objectstack/skillspatch.What the rule claims, measured against
origin/main481ade61rejectCredentialEvaluation(packages/objectql/src/credential-evaluation-guard.ts) judgeswhere(every branch), a{ $field }comparand, eachaggregations[i].filterand eachexpandentry'swhere. It answersINVALID_FIELD/ 400 for every caller except a system context.orderBy, andexpandentries'orderBy).rejectCredentialAggregation(packages/objectql/src/engine-count-aggregate.ts) refuses agroupByor aggregation field on a credential column,INVALID_FIELD/ 400. This guard has no system exemption.upsert/updateimport whosematchFieldsnames a credential column looks rows up through the guarded read, so each such row is reported failed and is not written. The rule says "an import row naming it fails", not "the import is refused".expandSearchOnAstdrops credential columns from the scan set, including one an object lists insearchableFields(packages/objectql/src/engine.ts, thecollectCredentialFieldsline in the search expansion). No 400 comes back.assertSearchFieldsAreSearchablerefuses an explicit$searchFieldsoverride only forinternal: truefields, not for credential types. So the rule says "search never scans it" and does not claim a refusal.isCredentialPresenceConditionaccepts barenull,$null/$exists/$emptywith a boolean,$eq: null,$ne: null, and$notover those. The rule names the four the card named.Tests
No tested behaviour changes, so there is no ablation. Skills token readings (
ceil(utf8 bytes / 4)), before → after:skills/objectstack-data/rules/security.mdskills/objectstack-data/evals/hooks-security-seeds-datasources.jsonobjectstack-data/SKILL.mdWhole published bundle (ratcheted, authored): 208076 tokens after, against ceilings summing to 217598. The only SKILL.md that could have moved is
objectstack-data/SKILL.md, and it is untouched.Acceptance notes
hooks-security-seeds-datasources.jsonwas at zero headroom onorigin/main. The two restating clauses cut here pay 71 bytes, and the new case costs about 440 bytes. Nothing else in the file restates itself without changing what a case expects. There are two ways out. One is the standing ruling 「A:先削重复,余额按实测提高」 (maintainer, 2026-10-27, decision card 「skills 修复卡的教学和 eval 都撞 token 天花板,怎么付?」), which would raise the row inscripts/check-skills-token-ratchet.mjsfrom 1573 to 1666. That file is outside this PR's declared file surface, so it is not edited here. The other is to drop the second commit and land only the rule. The seat decides which.searchableFieldsadvice the card asked for.Verification
Gates derived by
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackon head 1ad3325, with the exit code recorded before any pipe:44 commands: 43 derived plus `pnpm check:changeset-fixed` (its roster is under `.changeset/`); one red, the token ratchet
The five gates that first exited 3 (PREREQUISITE NOT MET: no
dist/) were re-run afterturbo run build --concurrency=2(115/115 tasks, lock VERDICT command-exit 0), and all five exit 0.--ranreconciliation: 43 derived, 43 run, 0 NOT-MEASURED, 0 UNRUN. Outside the derived list:pnpm --filter @objectstack/spec check:skill-examplesexits 0 (274 prose examples type-check).node scripts/check-skills-token-ratchet.mjsexits 1 with one failing row:hooks-security-seeds-datasources.json is 1666 tokens; the ratchet ceiling is 1573 (over by 93).security.mdpasses at 3686, ceiling 3687.🤖 Generated with Claude Code
https://claude.ai/code/session_016WV4d1QkPVVzNz3FJqb2iS