Skip to main content

SC Contractor Task Quality - Pre-Work Standard

Purpose

Defines what a well-formed ClickUp task looks like before it is assigned to a contractor. This standard is the human-readable companion to the symphony-flow task:lint CLI: every rule the linter enforces has a section here explaining what it checks, why it matters, and how to fix violations. The CLI's reason strings are intended to deep-link into this doc by section anchor.

Spec quality at assignment time directly reduces follow-up questions, accelerates contractor onboarding, and produces fewer rework cycles. Cheap to apply, expensive to skip.

Scope

Applies to every ClickUp task assigned to a contractor (acewebx, Ravish, or any future external contributor). Does not apply to:

  • SC-internal tasks (tracked in SC Operations space; different quality bar)
  • Tasks assigned to full-time SC team members who participated in scoping
  • Acknowledgment / placeholder tasks that exist purely for tracking

Linter rule index

The ten rules below are enforced by symphony-flow task:lint <task_id>. Each rule's field: name in the CLI output maps to a section anchor in this doc.

Linter fieldSection anchorSeverity
title#title-ruleBlocking
description#description-ruleBlocking
acceptance_criteria#acceptance-criteria-ruleBlocking
validation_evidence#validation-evidence-ruleAdvisory
context_links#context-links-ruleBlocking
priority#priority-ruleBlocking
due_date#due-date-ruleBlocking
estimated_effort#estimated-effort-ruleBlocking
tags#tags-ruleAdvisory
verbosity_budget#verbosity-budget-ruleAdvisory

Anchor convention: Linter field name → kebab-case + -rule suffix. acceptance_criteria becomes #acceptance-criteria-rule. CLI deep-link helper: '#' + field.replace(/_/g, '-') + '-rule'.

Blocking rules set exit code 1 if they fail; Advisory rules surface as warnings (exit code 0). The standard treats task:lint as advisory at the policy level: assigners are expected to run it and resolve findings — Blocking and Advisory both — before notifying the contractor.


title-rule

What it checks: The ClickUp task title is at least 8 characters and is not a generic placeholder (Untitled, TBD, TODO, Task, New Task, case-insensitive).

Pass example:

Build 4x3 ski-equipment-rental brand-pillar grid on home page

Fail example:

TODO
Fix it

How to fix:

  • Restate the title as a verb-object phrase: what is being done, to what.
  • 8 characters is the minimum, not the target. Most well-written titles are 30-70 characters.
  • The title is the only thing visible in list/board views. Treat it like a Slack notification preview.

Why it matters: A vague title forces the contractor to open the task to understand what it is, and forces the AM to repeat the description every time they discuss it in Slack. The cost compounds across every list-view glance.


description-rule

What it checks: The ClickUp task description is at least 50 characters of meaningful content.

Pass example: A description with a Summary, an Acceptance Criteria section, and at least one supporting link.

Fail example: An empty description, a one-line see chat, or as discussed.

How to fix: Use the structure:

## Summary

One paragraph: what you're asking for and why it matters.

## Acceptance Criteria

- Specific, verifiable condition 1
- Specific, verifiable condition 2

## Context / Supporting docs

- Spec: <drive-url>
- Copy: <drive-url>
- Reference: <github-or-public-url>

The 50-character minimum is a smoke test, not a quality bar. A 51-character description that says Please update the homepage to match the spec attached still fails the Context Links rule and the Acceptance Criteria rule. All three must pass independently.

The 50-character floor exists to keep stub tickets out of the queue. It is not an invitation to inline an entire SOP. Most good descriptions sit between 300 and 1,200 characters; see #verbosity-budget-rule for the upper bound.

Why it matters: A contractor reading the task in ClickUp on a phone, three time zones away, with no Slack context. Anything not in the description does not exist.


acceptance-criteria-rule

What it checks: The description contains either:

  • An H2/H3 heading matching ## Acceptance Criteria (or ### Acceptance Criteria), or
  • A line starting with Acceptance Criteria: (case-insensitive)

Pass example:

## Acceptance Criteria

- Home page loads in under 2s on mobile (Lighthouse)
- All 4 brand pillars present with correct images
- Carousel uses native WP plugin, no custom code

Fail example: No section header; criteria buried in paragraph form ("I'd like it to load fast and look like the spec...").

How to fix:

  • Use a real heading (## Acceptance Criteria is preferred -- ClickUp's markdown renderer handles it cleanly).
  • Each criterion is a bullet. Each criterion is testable: someone other than the AM can determine pass/fail by looking at the result.
  • Aspirational language (looks professional, feels modern) is not testable. Replace with verifiable statements (matches the design kit color palette, passes Lighthouse mobile score >= 90).

Why it matters: Without acceptance criteria, "done" is whatever the contractor says it is, and feedback rounds become re-scoping rounds. AC is the contract; everything else is context.


validation-evidence-rule

What it checks: The Acceptance Criteria section includes at least one bullet naming the concrete artifact the assignee will attach on completion. Severity is Advisory, not Blocking: legitimate exceptions exist (see "When to skip" below).

Pass example:

## Acceptance Criteria

- [ ] Both /sitemap.xml and /sitemap_index.xml return HTTP 200 with valid XML
- [ ] Working sitemap submitted to Google Search Console
- [ ] Evidence: screenshot of https://mootslaw.com/sitemap.xml loading in browser, attached as completion comment

Fail example: AC reads [ ] Sitemap is accessible with no evidence bullet anywhere in the description.

How to fix:

  • Add a final AC bullet starting with Evidence: and naming the artifact the assignee will attach.
  • Default to a screenshot of the outcome. Substitute a deploy URL, log link, PR URL, or other concrete reference when more appropriate to the work.
  • Specify where the evidence goes (typically "attached as completion comment") so the assignee doesn't have to guess.

When to skip: Three named exceptions where an Evidence bullet adds noise rather than signal.

  1. Outcome is self-evident from queryable system state — DNS records visible in the registrar, a PR merged into a branch the reviewer can open, a ClickUp task with status closed, a GHL workflow that the reviewer can open and inspect.
  2. Customer-side action — the assignee is coordinating a step the client physically performs (signing a document, paying an invoice). The assignee cannot capture evidence the client owns.
  3. Recurring routine task with a standing review pattern — e.g., a daily check whose results are aggregated in a separate dashboard. The dashboard is the evidence.

When skipping, the task author should make the reason discoverable: a one-liner in the Summary ("Outcome verifiable via DNS lookup, no screenshot needed") prevents future confusion.

Why it matters: "Done" needs a checkable trace. Without an explicit evidence ask, completion claims rest on the assignee's word — and the Review Standard's AC walk-through becomes the only safeguard. The Evidence bullet pre-commits the assignee to leaving an artifact that survives close-out. The artifact also short-circuits "did this actually get done?" questions when the reviewer or a future reader sees the task months later.

Reviewers still verify on the actual deliverable, not on the attached evidence alone — see the Review Standard's explicit guidance. The evidence is a leading indicator and an audit-trail artifact, not the verification itself.


What it checks: The description contains at least one URL (matching https?://...).

Pass example: A link to the spec doc in Google Drive, the ClickUp task for the parent CR, a GitHub commit, a Lighthouse report URL, or a reference site.

Fail example: No URLs at all in the description.

How to fix:

  • Link to the spec, the design doc, the parent CR/ticket, or the relevant reference.
  • Use shareable URLs only. Per Markdown Task File to ClickUp SOP §4, do not paste local filesystem paths (C:\..., H:\...). They are unreachable from ClickUp.
  • Verify the URL resolves before pasting. Default to team.symphonycore.com URLs (the live internal wiki — convert from repo path by stripping the leading numeric prefix and the .md suffix). If the publishing pipeline has stalled for a recently-added doc and the team URL 404s, fall back to a Drive PDF in My Drive/symphony-core-documents-storage/ or inline the relevant content. Do NOT paste GitHub blob URLs into tickets — they require repo access contractors don't have.
  • If the supporting content lives in Slack or a transcript, copy the relevant snippet into the description -- a Slack permalink expires when the contractor leaves the workspace.

Why it matters: A task with no context links is a black box. The contractor cannot verify their understanding without going through the AM, which adds latency to every step.


priority-rule

What it checks: The ClickUp priority field is set (not null, not "No Priority"). Valid values: Urgent, High, Normal, Low.

Pass example: Priority set to Normal (the default for most build work).

Fail example: Priority left at No Priority because the AM forgot to set it.

How to fix in the ClickUp UI: Open the task, click the priority flag icon, choose Urgent / High / Normal / Low.

Severity guidance:

  • Urgent -- client-visible blocker, revenue at risk, or compliance deadline. Reserve for genuine emergencies; if everything is urgent, nothing is.
  • High -- on the critical path of an in-flight project; another task is blocked on this.
  • Normal -- default. Steady-state build work, planned features, scoped CRs.
  • Low -- nice-to-have, polish, internal cleanup. Contractor may deprioritize.

Why it matters: Without a priority, contractors batch tasks chronologically (FIFO), which is rarely what the AM wants. Priority is a one-click cost that prevents AM having to nudge.


due-date-rule

What it checks: The ClickUp due_date field is set to a date (YYYY-MM-DD).

Pass example: Due date set to a realistic date that accounts for the contractor's existing workload and the estimated-effort value.

Fail example: Due date left blank.

How to fix in the ClickUp UI: Open the task, click the due date pill, pick a date.

How to estimate the due date:

  • Default for a Normal-priority task: 5-10 business days from assignment, depending on estimated_effort.
  • For Urgent: name a specific date and confirm in Slack that the contractor can meet it. Don't set 24-hour urgents without prior coordination.
  • For Low: set a due date anyway. "Whenever you have time" is operationally indistinguishable from "never".
  • Account for time zones: if the contractor is in India and SC is in ET, a 2026-05-15 due date implicitly means end-of-day IST on 2026-05-15, which is morning ET. State the timezone in the description if it matters.

Why it matters: Due dates are how the contractor sequences their own work across multiple SC tasks (and other clients). Without one, they will guess -- often wrong.


estimated-effort-rule

What it checks: The ClickUp time_estimate field is set to a value greater than zero (stored as milliseconds; ClickUp UI accepts hours/minutes).

Pass example: Estimate set to 4h for a half-day task.

Fail example: Time estimate not set, or set to zero.

How to fix in the ClickUp UI: Open the task, find the Time Estimate field, set a value (e.g., 4h, 30m, 1d).

How to estimate:

  • For build tasks: estimate the focused-work time, not the calendar time. A "4-hour task" is 4 hours of contractor work, even if it spans 2 calendar days.
  • Round to the nearest 0.5h for tasks under 4h; round to the nearest 1h for tasks 4h-8h; for tasks >8h, decompose into sub-tasks.
  • When uncertain, give a range in the description (Estimated 4-8 hours, likely closer to 6) and set the estimate to the midpoint.
  • For research / spike tasks where effort is genuinely unknown: set the estimate to the time-box you're willing to fund (e.g., 4h spike, report back at 4h regardless of completeness).

Why it matters:

  1. Contractor capacity planning. A contractor with 3 open tasks (2h, 2h, 16h) plans their week differently than one with 3 open tasks each marked "unknown".
  2. Budget reconciliation. Effort estimates feed the monthly invoice review (FR-050 time-entry validation -- see Review Standard).
  3. AM forecasting. Sum of open estimates is the AM's primary lead indicator for "is this contractor over- or under-loaded?".

tags-rule

What it checks: Every tag applied to the ClickUp task is listed in the SC ClickUp Tag Taxonomy. Severity is Advisory because some legacy tasks predate the taxonomy and would otherwise generate noise; new and recently-touched tasks are expected to pass.

Pass example: Task tags = [client/moots-law, domain:seo]. Both appear in the taxonomy.

Fail example: Task tags include urgent-pls-help, legacy-stuff, or fyi. None are in the taxonomy.

How to fix:

  • For each non-canonical tag, replace with the canonical equivalent from the taxonomy. Common replacements: urgent → use the ClickUp priority field, not a tag; fyi → drop entirely.
  • If the non-canonical tag captures a real recurring concept the taxonomy lacks, open a PR amending SC ClickUp Tag Taxonomy with: name, definition, when applied, who applies, automation implications. Land the PR before re-applying the tag.

Why it matters: A closed taxonomy makes tags useful as a reporting surface. Per-contractor quality patterns (quality:rework, quality:escaped), per-domain throughput, and per-blocker latency depend on tag values being stable and curated. Synonym drift and orphan tags ruin downstream filters. The quarterly audit (see the taxonomy doc) trims orphans; this rule prevents them from accumulating between audits.


verbosity-budget-rule

What it checks: The ClickUp task description fits on one ClickUp screen — approximately 1,200 characters / 200 words. Severity is Advisory, not Blocking: descriptions may legitimately exceed the budget when the referenced spec is genuinely inaccessible to the assignee (e.g., a one-off task with no SOP).

Pass example: A description with a short Summary, 4-6 verifiable AC bullets, 2-3 Reference doc links, and per-task one-off values.

Fail example: A description that inlines an entire 30-item validation checklist, a 6-row attendees table, an escalation matrix, and the full spec — all of which already live in linked source-of-truth docs. (Audited 2026-05-15: ticket 86ahg97mk came in at ~7,000 characters, ~6x the budget.)

How to fix:

  • If the description exceeds 1,200 characters, ask which content can move to a referenced doc instead. Most over-budget descriptions are duplicating content that already lives in an SOP, checklist, or client profile.
  • See Markdown Task File to ClickUp SOP §4.5 Anti-patterns for the specific patterns that drive bloat: full validation checklists, attendees tables, rollback procedures, source-of-truth tables.
  • Use the Thin Ticket Template as the starting skeleton.

Why it matters:

  1. Source-of-truth drift. Content inlined into a ticket is a snapshot; the SOP it copied from will evolve. Future readers can't tell which version is authoritative.
  2. Readability. Long descriptions tank ClickUp's UX — tables render as [table-embed:...] artifacts on mobile; the assignee misses items because they scroll past them.
  3. Maintenance cost. Every contact change in client-profile.md would otherwise require updating every ticket that re-typed the contact info. Linking to a single source eliminates that fan-out.
  4. Cognitive load. A thin ticket invites action. A bloated ticket invites paralysis.

Severity escalation

If task:lint fails on a contractor task that was already assigned (i.e., the contractor is already working on it), the AM should:

  1. Pause the contractor in Slack ("Hold for 10 min, fixing the spec").
  2. Run the fixes inline -- this is fast (most rules are 1-click in ClickUp).
  3. Re-run task:lint to confirm clean.
  4. Resume the contractor with a one-liner: "Updated, please refresh and proceed."

The cost of a 10-minute pause is much less than the cost of a wrong-spec deliverable. Don't let "in-flight" be a reason to skip the standard.

Revision History

DateVersionChangeAuthor
2026-05-121.0Initial release. Codified the 7 linter rules with anchor IDs matching the CLI field names.Symphony Core Systems Team
2026-05-151.1Added #verbosity-budget-rule (Advisory, 1,200-char target). Clarified #description-rule 50-char minimum is a floor, not a target. Captured 2026-05-15 audit of ticket 86ahg97mk (~7,000 chars, ~6x budget).Symphony Core Systems Team
2026-05-211.3Added #validation-evidence-rule (Advisory) — every ticket's AC nudges toward a concrete artifact (screenshot / URL / log link). Added #tags-rule (Advisory) — every tag must come from the SC ClickUp Tag Taxonomy. Driven by post-mortem of ticket 86ahkd043 (sitemap fix had no evidence ask).Symphony Core Systems Team