Skip to content

test(lint,service-automation): replace out-of-grammar record-created fixture token with record-after-create - #6636

Merged
os-project-manager merged 2 commits into
mainfrom
claude/issue-5957-flow-trigger-fixture-tokens
Aug 8, 2026
Merged

test(lint,service-automation): replace out-of-grammar record-created fixture token with record-after-create#6636
os-project-manager merged 2 commits into
mainfrom
claude/issue-5957-flow-trigger-fixture-tokens

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#5957

12 test fixtures spelled a flow start node's triggerType as record-created, a token that is outside the closed grammar the record-change trigger maps. Replaced all 12 with the in-grammar record-after-create. No assertion changed.

Why record-created is wrong

triggerTypeToHookEvents (packages/triggers/trigger-record-change/src/record-change-trigger.ts) is the canonical mapper, and its grammar is closed:

/^record-(before|after)-(create|insert|update|delete|write)$/

record-created has no phase segment, so it matches nothing and maps to zero hook events — the flow binds to the record-change trigger and then never fires, silently. That is exactly the shape flow-trigger-unknown-event reports, and since #5762 that rule is an error.

Verified against the source rather than the issue body's line numbers (the card was filed before several same-day merges):

  • grammar regex — packages/triggers/trigger-record-change/src/record-change-trigger.ts, triggerTypeToHookEvents
  • rule copy of the same grammar — packages/lint/src/validate-flow-trigger-readiness.ts, VALID_RECORD_TRIGGER

Why nothing was red before this PR

All three files call their own rule directly and none routes through validateFlowTriggerReadiness:

fileentry point
packages/lint/src/validate-flow-template-paths.test.tsvalidateFlowTemplatePaths
packages/lint/src/reference-integrity-suite.test.tsREFERENCE_INTEGRITY_RULES
packages/services/service-automation/src/record-lookup-expand.integration.test.tsautomation.execute on a booted LiteKernel

validateFlowTriggerReadiness is not a REFERENCE_INTEGRITY_RULES member (re-confirmed on this branch), so #5762's severity upgrade never reached these fixtures.

So this is a corpus fix, not a defect fix. Fixtures are read as examples: a token the platform's own lint calls "never fires", appearing 12 times in-repo, teaches the wrong spelling to every human and AI author reading the tests — which cancels out the reason flow-trigger-unknown-event exists.

triggerType is inert at all 12 sites (verified per-site)

Every fixture flow declares type: 'record_change', and the consuming predicate short-circuits on that before it ever reads the token:

// packages/lint/src/validate-flow-template-paths.tsfunctionisRecordTriggered(flow: AnyRec,startConfig: AnyRec): boolean{if(flow.type==='record_change')returntrue;// always taken hereconsttriggerType=typeofstartConfig.triggerType==='string' ? startConfig.triggerType : undefined;return!!triggerType&&triggerType.startsWith('record-');// and both tokens pass this anyway}

git grep over all three files finds no assertion naming triggerType, and the integration test registers no trigger at all — it drives automation.execute directly. Hence no assertion needed to follow the replacement.

Evidence

A green suite is not evidence on its own here — these fixtures are inert by hypothesis, so green was the expected outcome either way. Three independent measurements instead:

1. Token census (the deliverable itself), git grep over the tracked tree

tokenbeforeafter
triggerType: 'record-created' (out of grammar)12 — 10 / 1 / 1 across the three files0
triggerType: 'record-after-create' (in grammar)0 in these files12 — 10 / 1 / 1, same distribution

Repo-wide, record-created now appears 0 times in any form.

2. Reverse verification — direction predicted before running. Prediction: the platform's own rule reports the error for the old token and not the new one, while an unrelated control finding stays put for both (if the control vanished too, the probe had stopped reading the stack rather than the rule changing its verdict). Both tokens fed to the live rule on this branch:

[record-created] triggerTypeToHookEvents -> []
validateFlowTriggerReadiness -> 2 finding(s)
error flow-trigger-unknown-event
warning flow-draft-status-ambiguous (control)
[record-after-create] triggerTypeToHookEvents -> ["afterInsert"]
validateFlowTriggerReadiness -> 1 finding(s)
warning flow-draft-status-ambiguous (control survives)

Observed exactly as predicted: the error is gone, the control survives, and the mapper goes from zero hook events to afterInsert.

3. Suites still green (expected, and now meaningful because 1 and 2 show the right thing changed):

packages/lint Test Files 62 passed (62) Tests 1596 passed (1596)
packages/services/service-automation Test Files 70 passed (70) Tests 844 passed (844)
pnpm --filter @objectstack/lint typecheck -> tsc --noEmit, clean

Gates

Run one by one from .github/workflows/lint.yml (not from memory), against the committed tree with origin/main merged in:

  • ESLint job — all 31 steps PASS (pnpm lint, check:slot-lookup, check:query-options-erasure, check:verify-stand-in, check:nul-bytes, check:doc-authoring, check:docs-audit-scope, check:role-word, check:quick-reference-counts, check:adr-anchors, check:org-identifier, check:authz-resolver, check:service-providers, check:route-envelope, check:error-code-casing, check:wildcard-fallthrough, check:meta-type-normalized, check:init-service-contract, check:durability-log-level, check:startup-registry-verdict, check:objectui-changeset, check:release-notes, check:release-body, check:node-version, check:workflow-status-functions, check:shard-attestation, check:published-files, check:engine-double-contract, check:resume-authority-declared, check:merge-driver, check:spec-parsed-alias)
  • TypeScript Type Check job — all 22 script steps PASS, plus the full-workspace turbo run build (70 tasks) and turbo run typecheck (120 tasks)

packages/lint is one of the packages whose test-exclusion behaviour makes local-green / CI-red possible, which is why the whole list was run rather than just the package's own tests.

skip-changeset

No changeset. This PR touches only*.test.ts fixture string literals — no source file, no published artifact, no authorable surface, nothing a user can observe or depend on. There is no release note to write, so a changeset would be a row about nothing. Label applied on the PR.

Explicitly out of scope

The non-record--prefixed family named in the card — on_create (x2), on_update (x1), onCreate (x1) — is not touched here, per the ruling on #5957. Those never match flow-trigger-unknown-event at all: the engine treats any non-record- token as "no record trigger" and silently degrades the flow to manual. Whether that shape deserves a diagnostic is a separate lint-capability judgement, so it is filed as its own unassigned finding issue rather than folded in. No lint rule is added in this PR.


Generated by Claude Code

…` fixture token with `record-after-create`
12 test fixtures spelled a flow start node's `triggerType` as
`record-created`, which is outside the closed grammar the record-change
trigger maps:
/^record-(before|after)-(create|insert|update|delete|write)$/
(triggerTypeToHookEvents, packages/triggers/trigger-record-change)
The token is missing its phase segment, so it maps to ZERO hook events —
the exact shape `flow-trigger-unknown-event` reports, and an `error`
since #5762.
Nothing is red today: all three test files call their own rule directly
(`validateFlowTemplatePaths` / `validateReferenceIntegrity` / the runtime
expand integration) and none routes through `validateFlowTriggerReadiness`,
which is not a `REFERENCE_INTEGRITY_RULES` member. This is a corpus fix,
not a defect fix: fixtures are read as examples, and a token the platform's
own lint calls "never fires" appearing 12 times in-repo teaches the wrong
spelling to anyone (and any AI) reading the tests.
`triggerType` is inert at all 12 sites — every fixture flow declares
`type: 'record_change'`, so `isRecordTriggered` returns from its first
branch without reading the token, and no assertion in any of the three
files names `triggerType`. No assertion changes.
Refs #5762, #3427.
Fixes#5957
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F8q5J1MQyocgtNspb15fSn
@vercel

vercelBot commented Aug 8, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 8, 2026 7:51am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

@os-project-manageros-project-manager added skip-changeset PR has no user-facing published change; bypasses the changeset gate size/s and removed size/s labels Aug 8, 2026 — with Claude
@os-project-manager
os-project-manager marked this pull request as ready for review August 8, 2026 07:52
@os-project-manager
os-project-manager added this pull request to the merge queueAug 8, 2026
Merged via the queue into main with commit 487a197Aug 8, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-5957-flow-trigger-fixture-tokens branch August 8, 2026 08:19
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gatetests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

12 处测试 fixture 用 triggerType: 'record-created' —— 平台自己的 lint 判它永不触发(#5762 后是 error)

2 participants

@os-project-manager@claude