Skip to content

test: retire 17 family rows strict lint now owns; keep the i18n gate and the props parse sweep (#1582) - #2012

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-1582-family-regrade
Oct 8, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-1582-family-regrade

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #1582
Part of #1583
Fixes #1584
Part of #1585
Fixes #1586
Fixes #1805
Clause-②: no

The one retirement PR for the family re-grade (ruling hotcrm-R74 item 4 B; re-grade 6053840674, fold plan 6053925467). Every row was re-ablated on this PR's base b54380cf (the two-package artifact from #1907) before its local assertion was deleted. 17 of the 19 planned rows retire. 2 rows stay, because the re-ablation found cases that objectstack lint --strict does not report on this base. #1583 and #1585 therefore get Part of, not a closing line: each keeps one row, listed under "Rows kept after re-ablation".

What changed

Re-ablation on b54380cf, per case (before deletion)

Method: same as the re-grade. Each case was one anchored mutation through ablation-replace.mjs. It ran pnpm lint --json (objectstack lint --strict), then the owning test file. A trap restored the tree, and the restore was proven three ways: blob hash equals HEAD, git diff HEAD is empty, and git status is clean. Baseline on b54380cf: errors 0, warnings 0, suggestions 18, failing 0, strict true, exit 0. In every row below the local assertion was also red.

retired row rule id cases: lint exit + rule
F1 inert decision config.condition flow-inert-node-condition top level 1 · nested in loop/try 1 · service-module flow 1 (two flows) · blank '' 1 expression-invalid · null 0 (same as the re-grade: a null states no predicate, so it is outside the assertion's rationale)
F1 view-tab-label-inert spec 17.5.0 schema tombstone list.tabs 1 · listViews.*.tabs 1 (config load refuses view.list.tabs was removed in @objectstack/spec 17.5.0, no rule id)
F2 record:details / highlights / path fields page-field-unknown highlights 1 · path statusField 1 · details section field 1 · service-module page 1
F2 field-level group resolves field-group-undeclared 1
F2 no empty group field-group-empty 1
F2 no fully hoisted group field-group-shadowed 1
F2 skill tool names resolve ai-skill-tool-unresolved plain 1 · action_ 1 · wildcard 1 · service-module skill 1 · a name only a stack.tools record serves: 0, held by the kept does not lean on AI tool metadata (red)
F2 form section fields form-field-unknown default form 1 · formViews object entry 1
F3 A1 dataset chart-dataset-unknown chartless 1 · charted 1 · joined block 1 · service-module report 1
F3 A3 xAxis chart-dimension-unknown 1
F3 A4 rows/columns/values chart-dimension-unknown · chart-measure-unknown rows chartless 1 · columns 1 · values 1 · rows charted 1 · rows joined block 1 · service-module rows + values 1 (both ids)
F3 A8 preset comparand filter-preset-comparand bare on a widget 1 · $eq on a widget 1 · $in in a report 1
F4 option keys by value translation-option-key-unknown extra key en 1 · zh-CN 1 · English-label key 1 · options on a field with none 1 · unknown field 1 translation-target-unknown
F4 apps.*.navigation orphans translation-target-unknown unknown nav id 1 · unknown app 1
F4 section label without name translation-section-name-missing view form 1 · formViews 1 · page record:details in tabs 1
F5 FLS unqualified / real field security-fls-unqualified-key · security-fls-unknown-field bare key 1 · unknown field 1 · empty remainder 1 · unknown object 0 (kept branch, deliberate per objectstack PR #16998)
F5 RLS predicates (both sweeps) rls-predicate-unknown-field · -unknown-user-variable · -unenforceable using: unknown field 1 · unknown leading field 1 · current_user.nope 1 · nested path 1 · function call 1 · check (new, not in the re-grade): unknown field 1 · current_user.nope 1 · function call 1 · unknown policy object 0, held by the kept every policy targets an object the same set grants (red)

After deletion, at 68fe1b2c: one case per retired row was re-run with lint only (18 probes). Every probe gave exit 1 with the same rule id, or the same schema refusal for list.tabs.

Rows kept after re-ablation (not retired)

  1. F2: component-props parse sweep (every page component's properties parse against its own ComponentPropsMap entry). This case is new; the re-grade did not probe it. A page component nested in another component's properties, with its own properties absent and a contract that requires keys, gets exit 0. Measured on a nested record:related_list, a nested page:accordion and a nested element:text. The local sweep is red on all three. Control: the same edit on a top-level record:path gets exit 1 (component-props-invalid). Mechanism: PageComponentSchema defaults a top-level component's properties to {}, but nothing parses a nested component, and validateComponentProps skips one with if (!props) continue. The three nested types in use today are also held, by chance, by other kept tests. A new nested type with required props would be held by nothing. The test file is unchanged.
  2. F4: the lint:i18n-gate gate. This is a regression against the re-grade. On 68fe1b2c (the gate restored) one non-default-locale (zh-CN) entry was deleted per class: object, field, option, section, view, action, navigation, dashboard, widget, dataset, page and flow. All 12 classes gave pnpm lint exit 0 (plain and --json) and gate exit 0. On c529de2b the re-grade measured exit 1 on all 12. Mechanism: the CLI's translation-coverage pass runs computeI18nCoverage on the composed top level. Since Packaging: sales becomes the type: app package and service a type: module — composeStacks(…, { manifest: 'preserve' }), navigation contributions, two-entry packages[] #1907, composeStacks(…, { manifest: 'preserve' }) leaves that level with only manifest, packages and i18n: no translations and no metadata. Run in memory over the union-of-packages stack, the same deletion is reported (warning zh-CN navigation apps.crm_enterprise.navigation.nav_home.label). The kept local completeness tests are red for field, option, section, view, action, widget and page. Nothing in pnpm verify is red for object, navigation, dashboard, dataset or flow. The gate removal could not be shown to lose nothing, so per the dispatch rule the gate stays, and the platform defect is reported for the seat to file upstream.

KEEP rows in the files this PR edits: byte-identity

Method: each it(…) block was extracted from b54380cf and from HEAD, and the text was hashed (sha1, first 12 hex). Across the 8 edited test files, 118 blocks are byte-identical. Seventeen were removed (the retired rows) and one was added (the FLS split). One block is comment-only: sees a real navigation tree and an apps.*.navigation table in every locale, whose inline comment was rewritten because it pointed at the retired orphan sweep. Its non-comment lines hash equal (44031195) at both revisions. The KEEP rows of the table, and the holders named above:

file › assertion base HEAD
flow-decision-authority › every decision node actually decides something ff12fefc4618 ff12fefc4618
metadata-references › every page component's properties parse against its own ComponentPropsMap entry (kept, row 1 above) 7a3fefb3d34d 7a3fefb3d34d
metadata-references › every page component type has a props contract to parse against 985131628dce 985131628dce
field-groups-coverage › %s declares fieldGroups 3c63094cf981 3c63094cf981
view-references › kanban groupByField is a select field with options 64c37d829e9b 64c37d829e9b
skills-integrity › does not lean on AI tool metadata, which never executes (holder) 8af703ba057d 8af703ba057d
i18n-references › translated object and field keys name real objects and fields 4c90ff38134e 4c90ff38134e
i18n-references › no locale carries a _views entry for a view the stack does not ship 8222ee4af2da 8222ee4af2da
i18n-references › every authored field label and help string is translated 4bcc95a5d1d6 4bcc95a5d1d6
i18n-references › every option value has a translated label in every locale 341603826787 341603826787
i18n-references › every form and detail-page section heading is translated c59cb84472f6 c59cb84472f6
i18n-references › every canonical view label is translated in every locale 983e0ac81a02 983e0ac81a02
i18n-references › every action has a label entry in every locale pack 11584fdb8f9e 11584fdb8f9e
i18n-references › every dashboard widget has a translated title and description 764a555ec7bf 764a555ec7bf
i18n-references › every page has translated nav copy and header copy 89afa7bb9a85 89afa7bb9a85
i18n-references › every reference-rail object has a translated label in every locale 0775ced90511 0775ced90511
i18n-references › every view empty state is translated 8ff1ee70b6e9 8ff1ee70b6e9
i18n-references › every action parameter label is translated 00d69619006f 00d69619006f
authorization-coverage › every business object is granted in at least one permission set c878f28a53d3 c878f28a53d3
authorization-coverage › every object nav item is readable by at least one permission set bb3a81aea126 bb3a81aea126
authorization-coverage › every policy targets an object the same set grants (holder) 140aa8fe8c8a 140aa8fe8c8a
authorization-coverage › a sharing rule only targets an object whose OWD lets shares apply a317ec6e9049 a317ec6e9049
authorization-coverage › the guest set carries no export bit (ADR-0090 D9 anchor rule) 2ca385723718 2ca385723718

The gate's files have an empty git diff b54380cf HEAD: scripts/check-lint-i18n-gate.mjs, test/lint-i18n-gate.test.ts, package.json, both workflows, test/script-main-guard.test.ts, scripts/lib/main-module.mjs and test/verify-log-decoy-pin.test.ts.

F4 gate-removal proof: not obtained, gate kept

deleted zh-CN entry (class) pnpm lint pnpm lint --json failing gate local test red
object, navigation, dashboard, dataset, flow 0 0 0 none
field, option, section, view, action, widget, page 0 0 0 the matching completeness assertion in i18n-references

Stale prose corrected in this PR

  • test/i18n-references.test.ts. The completeness block comment said pnpm lint runs with --skip-i18n and that lint exits 0 on warnings. It now gives what was measured: the run is strict, but its i18n coverage reports nothing on this artifact. The View-labels comment, the nav block comment and the "no _sections category" sentence (17.7.0 has i18n/missing-section) were corrected the same way.
  • src/sales/profiles/{sales-manager,marketing-user}.profile.ts, comments only. They said "liveness: dead in 17.6.0". The installed 17.7.0 liveness/permission.json marks props.rowLevelSecurity.children.label and .description "status": "live" (verifiedAt 2026-10-03, "RE-GRADED dead → live … the permission editor's Row-Level Security section heads each policy card with pol.label").
  • Comments in the edited test files that named a retired assertion. They now name the rule id instead: flow-decision-authority, field-groups-coverage, skills-integrity, analytics-integrity, view-references (also its view-tab-label-inert pointer) and the metadata-references split map.

Outside the claimed surface, edited because this PR's retirements made the text false:

  • content/docs/analytics/cubes.mdx, .zh-Hans.mdx and .zh-Hant.mdx. These said test/analytics-integrity.test.ts fails the build on an unresolved dataset, measure or dimension name; they now credit objectstack validate and objectstack lint --strict.
  • docs/ARCHITECTURE.md and docs/developers/code_examples.md. These named test/skills-integrity.test.ts as the tool-name resolver and said PLATFORM_TOOLS is transcribed there.

Not edited here, now stale. Both are src comments, and the dispatch allows only the two profile comments under src/. They are listed for #1919, the src-comment card that follows this PR:

  • src/revenue/objects/opportunity_line_item.object.ts:69: "test/field-groups-coverage.test.ts pins it" (field-group-shadowed).
  • src/service/flows/case-escalation.flow.ts:123: "test/flow-decision-authority.test.ts enforces that".

Verification

  • pnpm verify at 68fe1b2c exited 0 through the verify lock (VERDICT command-exit 0). Validate: "✓ Validation passed". Typecheck: clean. Lint: "18 suggestion(s)", exit 0. lint:i18n-gate: "✓ i18n lint gate: 0 i18n/missing-* issues". Hygiene: "✓ source hygiene clean". Token ratchet: "✓ source token ratchet clean". Build: "✓ Build complete". Test: "Test Files 178 passed (178) · Tests 3814 passed | 1 skipped (3815)".
  • Probe totals: 104 probe runs in 15 batches. Every probe log records RESTORED-PROVEN, the batch runner reported no unproven restore, and every batch ended with "TREE CLEAN after batch". Four probes were refused by ablation-replace because the anchor was contained in its replacement (no-op, restored), and each was redone with a unique anchor.

Acceptance notes (for the seat; not filed by this PR)


Generated by Claude Code

claude added 3 commits October 8, 2026 07:36
Per-row deletion after re-ablation on b54380c: flow-inert-node-condition,
the view.list.tabs schema tombstone, page-field-unknown, form-field-unknown
and field-group-undeclared / -shadowed / -empty each fire under
`objectstack lint --strict` on every case the local assertion covered.

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
…ns (#1583-#1586, #1805)

Per-row deletion after re-ablation on b54380c, each case firing under
`objectstack lint --strict`: ai-skill-tool-unresolved, chart-dataset-unknown,
chart-dimension-unknown, chart-measure-unknown, filter-preset-comparand,
translation-option-key-unknown, translation-target-unknown (navigation),
translation-section-name-missing, security-fls-unqualified-key,
security-fls-unknown-field, and the rls-predicate-* family. Kept: the FLS
unknown-object branch, "every policy targets an object the same set grants",
and the component-props parse sweep (a nested component with no `properties`
is silent at lint).

The i18n lint gate goes whole: script, test, package.json script, its verify
step and both CI steps, with its roster entries in script-main-guard and
verify-log-decoy-pin. Stale prose in the touched files is corrected, as are
the two profile comments the 17.7.0 liveness ledger contradicts.

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
Re-ablating the gate removal on the committed tree, a deleted zh-CN label
of each i18n/missing-* class (object, field, option, navigation, page,
section, view) leaves `pnpm lint` at exit 0: on the two-package artifact the
CLI's translation-coverage pass reads the composed top level, which carries
no translations and no metadata. The gate reads the same lint report, so the
row is kept, byte-identical to main, and reported as a regression against the
re-grade. The i18n-references prose that claimed strict lint now fails on a
non-default-locale gap is corrected to what was measured.

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Oct 8, 2026 8:02am UTC

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation ci/cd CI plumbing and the verification pipeline metadata Declarative metadata — schema, security posture, UI surfaces labels Oct 8, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 8, 2026 08:11
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 8, 2026
Merged via the queue into main with commit 99d290a Oct 8, 2026
11 checks passed
zhuangjianguo pushed a commit that referenced this pull request Oct 9, 2026
…ectories

Comment lines only, same rule as the sales commit. The case-escalation flow's
note names the platform lint rule instead of the test row #2012 retired.

Claude-Session: https://claude.ai/code/session_018Mk4tab2eCyY41UTWK7y7V
Co-authored-by: Claude <noreply@anthropic.com>
zhuangjianguo pushed a commit that referenced this pull request Oct 9, 2026
…ectories

Comment lines only. quote.hook.ts's two billing-handoff notes name the
contract-activated flow, the one of the two split successors that POSTs a
contract's payment_terms and contract_type; the line-item note names the
platform lint rule instead of the test row #2012 retired.

Claude-Session: https://claude.ai/code/session_018Mk4tab2eCyY41UTWK7y7V
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment