Skip to content
Lint & Fix Workflow
AutoXXS (320px)XS (375px)SM (640px)MD (768px)LG (1024px)XL (1280px)XXL (1536px)
SketchMaterialiOSTamagui
DataInjectionKeyPatternsServiceTransactionProcessResearchProductQualityPerformanceSpecDomainFunctionTechnologyArchitectureConfigMiddlewareDataDatabaseDrizzleMigrationModelop-sqliteSchemaSQLState ManagementDraftKeystoneMergePatchPatchesPersistenceReactiveRedoStoreUndoTestingDeviceFactoryIsolationTypeScriptZodTopicsCommunicationBidsNVCDesignDesign ImplicationsEducationPedagogyFoundationsPsychologyAttachmentFloodingRelatingAuthentic RelatingUIEditorReact Native

Lint & Fix Workflow

Workflow Lint & Fix Workflow
agent starfix
tags
workflowlint

Trigger: lint directive, or any time the user asks to β€œfix errors”, β€œfix issues”, or β€œclean up the spec”.

Phase 1 β€” Fetch issues

get_system_status()

If the result is an empty list, report β€œNo issues found” and stop.

Group the returned issues by file. Within each file group, deduplicate issues with the same path and message (the compiler can emit the same error twice for the same attribute in some edge cases). Report the triage summary:

{n} issues in {m} files (errors: {x}, warnings: {y})

Phase 2 β€” Classify each issue

For each issue, determine its class before touching any file:

ClassHow to recogniseFix strategy
Missing required attributemessage: "Required" + path ends in an attribute name (e.g. .source, .reaction, .type, .code)Add the missing attribute with a reasonable default or a TODO value
Wrong property name formatmessage contains "camelCase or kebab-case"The name attribute on a \{% property %\} tag uses camelCase; convert to kebab-case
Wrong id prefixmessage contains "must start with" or "invalid prefix"Rename the id or name attribute to use the correct prefix from the naming table
Unknown attribute / wrong attribute namemessage contains "unknown attribute" or "did you mean"An agent used the wrong attribute name on a tag; rename to the correct one
Broken cross-document referencetype: "link"The qualified id does not resolve; check if the target was renamed or mistyped
Semantic / logic issuetype: "semantic"Requires judgment β€” do not auto-fix; flag for the user

Skip any issue whose class is semantic or link β€” report them as β€œrequires manual review” and move on.

Phase 3 β€” Fix file by file

For each file that has at least one auto-fixable issue:

  1. Read the file in full β€” never edit blindly.
  2. Apply all fixes for that file in one pass β€” do not write between each fix.
  3. Prefer the narrowest edit: change only the failing attribute, not the surrounding tag structure.
  4. If a missing required attribute has no obvious value (e.g. source on a \{% policy %\} with no trigger context), write source="TODO" and note it in the report.
  5. Write the corrected file and record what changed.

Common fixes quick-reference:

Error path patternTagFix
tag:policy.source{% policy %}Add source="TODO" attribute
tag:policy.reaction\{% policy %\}Add reaction="TODO" attribute
tag:operation[...].type\{% operation %\}Add type="query" or type="command" based on the operation name
tag:error[...].code β€” Required\{% error %\}Add code="TODO" attribute
tag:error[...].code β€” SCREAMING_SNAKE_CASE\{% error %\}Code must be SCREAMING_SNAKE_CASE (e.g. NOT_FOUND, VALIDATION_FAILED). Convert the error id to SCREAMING_SNAKE_CASE: task-type-not-found β†’ TASK_TYPE_NOT_FOUND. Never use integer HTTP codes.
tag:rule[...].force β€” Required\{% rule %\}Add force="must" or force="should" based on constraint strength. Default to force="must" unless the rule is advisory.
frontmatter.tags β€” Expected array, received stringAny .mdoc frontmattertags must be a YAML array, not a space-separated string. Convert tags: foo bar baz β†’ tags: [foo, bar, baz].
tag:property[...].name β†’ camelCase\{% property %\}Rename name="fooBarBaz" β†’ name="foo-bar-baz"
tag:*.properties.N.name β†’ camelCaseinline \{% property %\} inside action/event/operationSame: convert name to kebab-case

Wrong attribute name pattern: When an agent confuses attribute names (e.g. writes trigger= instead of source=, or body= instead of reaction=), the error appears as "unknown attribute". Read the tag schema from get_instructions("starspec/tag/{tagname}") if unsure of the correct attribute name before fixing.

Phase 4 β€” Re-verify

After all files have been written, call get_system_status() again. Compare the new issue list against the original:

  • Issues resolved β†’ list them as fixed
  • Issues remaining that were auto-fixable β†’ escalate to user (something structural may be wrong)
  • Issues remaining that were skipped (semantic/link) β†’ list them as β€œrequires manual review”

Phase 5 β€” Report

Output a concise summary:

Lint complete β€” {n} fixed, {m} require manual review
Fixed:
domains/foo.domain.mdoc β€” added policy.source, policy.reaction
domains/bar.domain.mdoc β€” converted 3 property names to kebab-case
Requires manual review:
flows/baz.flow.mdoc β€” broken ref: feature/nonexistent (link error)
domains/qux.domain.mdoc β€” semantic: step order inconsistency

Do not re-display the quick-reference card after a lint run β€” the user is in a fix-focused context, not a creation context.


Do’s and Don’ts

Do:

  • Read each file in full before editing β€” never edit blindly
  • Apply all fixes for a file in one pass
  • Prefer the narrowest edit: change only the failing attribute, not the surrounding tag structure
  • Re-verify with get_system_status() after all fixes are applied
  • Report both fixed and remaining issues in the summary

Don’t:

  • Auto-fix semantic or link issues β€” flag them for manual review
  • Re-display the quick-reference card after a lint run
  • Write TODO values when a reasonable default can be inferred from context
  • Write between individual fixes for the same file

Definition of Done

  • All lint issues classified (error, warning, info)
  • All errors fixed or explicitly deferred by user
  • Re-lint returns zero errors