DEV Community

Dakota Wu
Dakota Wu

Posted on

Weekend Drift in SLA Deadlines: Characterize First, Extract Next-Open Last

A support platform asked a coding assistant to tidy a 400-line first-response SLA module last quarter. The assistant produced a calendar package, a smaller public surface, and unit tests that stayed green on synthetic weekdays. Staging then placed Friday 16:55 urgent tickets onto Monday 09:00 instead of Friday 17:00. Production treated 17:00 as inclusive for urgent severity and exclusive for normal severity, inside one nested branch.

Why the tidy extract moved the clock

Cleaner names did not preserve the cutoff table that operators had learned from escalations. The nested branch mixed timezone conversion, holiday lookup, severity multipliers, and weekend rolling in a single return path. Characterization tests would have failed the extract before review, because Friday 16:55 urgent is a known production shape. The lesson is operational rather than stylistic: freeze observable deadlines, then change one seam.

Industry talk about AI-assisted coding often frames the risk as slow skill atrophy for working engineers. For messy calendar code the nearer risk is quieter: a helper extract that inverts one inclusive boundary. Agents optimize for names and structure, while production SLAs optimize for the last minute that still counts. Those two objective functions diverge on Friday afternoons, month-end cutoffs, and company holiday eves.

A reviewer cannot hold every cutoff in working memory while reading a 400-line module. A fixture table can hold them, if the rows come from production-shaped timestamps rather than tidy round hours. The sections below build that table, hash it, and only then extract next-open. The allowed extract is a single next-open function, not a rewrite of the calendar package.

Inventory implicit calendar rules

Do not start from the helpers you wish the module already exposed in production. Start from tickets that already missed or barely met first response in staging logs. Collect a compact rule inventory that a reviewer can check without reading the module. The inventory below is a decision table for characterization, not a proposed redesign.

  1. Convert created_at to America/New_York before any weekday or clock comparison runs.
  2. Treat 17:00 as inclusive for urgent and exclusive for normal on the created local day.
  3. Skip Saturday, Sunday, and dates present in the holiday CSV after the cutoff check.
  4. Open the next business day at 09:00 local if the ticket misses the close window.
  5. Keep month-end and year-end rows, because rolling 31 January can land on a weekend holiday eve.
created_local severity holiday_csv expected seam
Fri 16:55 urgent no same-day 17:00
Fri 17:00 urgent no same-day 17:00
Fri 17:00 normal no Mon 09:00
Fri 16:55 normal no same-day 17:00
Sat 10:00 urgent no Mon 09:00
Thu 16:00 normal Fri holiday Mon 09:00
31 Jan 16:55 urgent no 31 Jan 17:00 or next open

The table is the contract. Named functions are optional until that contract stops moving under a hash.

Worked example: a tangled first-response deadline

The module below is a compressed stand-in, not a copy of any vendor SLA engine. It keeps several rules in one function so an extract has somewhere real to fail. Treat timestamps, holidays, and expected hashes as fixtures for this article, not as production measurements.

# sla_deadline.py
from __future__ import annotations

from datetime import datetime, time, timedelta
from zoneinfo import ZoneInfo

TZ = ZoneInfo("America/New_York")
OPEN = time(9, 0)
CLOSE = time(17, 0)
HOLIDAYS = {"2026-01-01", "2026-07-03", "2026-07-04", "2026-12-25"}


def first_response_deadline(created_at: datetime, severity: str) -> datetime:
    local = created_at.astimezone(TZ)
    sev = severity.lower().strip()
    close_inclusive = sev == "urgent"

    def is_holiday(d) -> bool:
        return d.date().isoformat() in HOLIDAYS

    def is_weekend(d) -> bool:
        return d.weekday() >= 5

    # Nested on purpose: cutoff, weekend, and holiday share one return path.
    cursor = local
    if is_weekend(cursor) or is_holiday(cursor):
        cursor = datetime.combine(cursor.date(), OPEN, tzinfo=TZ)
        while is_weekend(cursor) or is_holiday(cursor):
            cursor = cursor + timedelta(days=1)
            cursor = datetime.combine(cursor.date(), OPEN, tzinfo=TZ)
        return cursor

    clock = cursor.timetz().replace(tzinfo=None)
    if clock < CLOSE or (close_inclusive and clock == CLOSE):
        return datetime.combine(cursor.date(), CLOSE, tzinfo=TZ)

    cursor = datetime.combine(cursor.date() + timedelta(days=1), OPEN, tzinfo=TZ)
    while is_weekend(cursor) or is_holiday(cursor):
        cursor = cursor + timedelta(days=1)
        cursor = datetime.combine(cursor.date(), OPEN, tzinfo=TZ)
    return cursor
Enter fullscreen mode Exit fullscreen mode

Friday 17:00 urgent stays on Friday. Friday 17:00 normal rolls to Monday 09:00. That single comparison is the defect surface most calendar cleanups rewrite by accident.

Turn the decision table into an oracle

Write fixtures as rows, not as assertions scattered through test names. ISO timestamps keep timezone offsets visible when a later extract starts calling utcnow. The loader below is the characterization suite; it does not claim to be a domain model.

# characterize_sla.py
from __future__ import annotations

import csv
import hashlib
import json
from datetime import datetime
from pathlib import Path

from sla_deadline import first_response_deadline

FIXTURE = Path("fixtures/sla_deadlines.csv")


def load_rows(path: Path) -> list[dict[str, str]]:
    with path.open(newline="", encoding="utf-8") as handle:
        return list(csv.DictReader(handle))


def observe(row: dict[str, str]) -> dict[str, str]:
    created = datetime.fromisoformat(row["created_at"])
    got = first_response_deadline(created, row["severity"])
    return {
        "id": row["id"],
        "created_at": created.isoformat(),
        "severity": row["severity"],
        "deadline": got.isoformat(),
    }


def oracle_payload() -> list[dict[str, str]]:
    rows = load_rows(FIXTURE)
    observed = [observe(row) for row in rows]
    return sorted(observed, key=lambda item: item["id"])


def oracle_hash(payload: list[dict[str, str]]) -> str:
    blob = json.dumps(payload, separators=(",", ":"), sort_keys=True)
    return hashlib.sha256(blob.encode("utf-8")).hexdigest()


if __name__ == "__main__":
    payload = oracle_payload()
    digest = oracle_hash(payload)
    Path("artifacts").mkdir(exist_ok=True)
    Path("artifacts/sla_oracle.json").write_text(
        json.dumps({"sha256": digest, "rows": payload}, indent=2),
        encoding="utf-8",
    )
    print(digest)
Enter fullscreen mode Exit fullscreen mode

Seed the CSV with production-shaped minutes, not only 09:00 and 17:00. Include a Friday 16:55 urgent row, a Friday 17:00 pair, a Saturday create, and a Thursday before a Friday holiday. If the team has sanitized staging exports, prefer those timestamps over invented round numbers.

id,created_at,severity
fr-1655-u,2026-07-10T16:55:00-04:00,urgent
fr-1700-u,2026-07-10T17:00:00-04:00,urgent
fr-1700-n,2026-07-10T17:00:00-04:00,normal
fr-1655-n,2026-07-10T16:55:00-04:00,normal
sat-1000-u,2026-07-11T10:00:00-04:00,urgent
thu-pre-holiday,2026-07-02T16:00:00-04:00,normal
Enter fullscreen mode Exit fullscreen mode

Pin the digest before anyone opens an extract branch. Re-running the oracle on the messy module should print the same SHA-256. Any later candidate that changes a deadline fails the hash even when new unit tests stay green.

python characterize_sla.py
git add fixtures/sla_deadlines.csv artifacts/sla_oracle.json sla_deadline.py
git commit -m "Pin SLA deadline oracle before next-open extract"
Enter fullscreen mode Exit fullscreen mode

Fail the oversized extract on purpose

Label the next block as a rejected candidate, not as a recommended design. An assistant will often replace holidays, timezones, and cutoffs in one commit because the names look related. Run the oracle against that shape and keep the log.

# rejected_calendar_package.py
from datetime import datetime, time, timedelta
from zoneinfo import ZoneInfo

# Proposed rewrite: one close rule for every severity.
CLOSE = time(17, 0)


def first_response_deadline(created_at: datetime, severity: str) -> datetime:
    local = created_at.astimezone(ZoneInfo("America/New_York"))
    if local.timetz().replace(tzinfo=None) <= CLOSE and local.weekday() < 5:
        return datetime.combine(local.date(), CLOSE, tzinfo=local.tzinfo)
    nxt = local + timedelta(days=1)
    while nxt.weekday() >= 5:
        nxt += timedelta(days=1)
    return datetime.combine(nxt.date(), time(9, 0), tzinfo=local.tzinfo)
Enter fullscreen mode Exit fullscreen mode

That candidate collapses inclusive and exclusive 17:00 handling and drops the holiday CSV. The oracle hash moves on fr-1700-u and thu-pre-holiday together. Record both row identifiers in the review note so the extract discussion stays on deadlines, not on taste.

The smallest safe change is next-open

After the oversized rewrite fails, extract only the loop that advances a local datetime to the next business open. Leave cutoff inclusivity inside first_response_deadline until a second oracle row family demands a second seam. The helper below is the entire allowed diff for the first pass.

# next_open.py
from datetime import datetime, time, timedelta

OPEN = time(9, 0)


def next_open(cursor: datetime, is_closed) -> datetime:
    """Advance to 09:00 on the next day that is_closed reports as open."""
    probe = datetime.combine(cursor.date(), OPEN, tzinfo=cursor.tzinfo)
    if probe <= cursor or is_closed(probe):
        probe = datetime.combine(
            (cursor + timedelta(days=1)).date(), OPEN, tzinfo=cursor.tzinfo
        )
    while is_closed(probe):
        probe = datetime.combine(
            (probe + timedelta(days=1)).date(), OPEN, tzinfo=cursor.tzinfo
        )
    return probe
Enter fullscreen mode Exit fullscreen mode

Wire it with a local closure so holiday and weekend rules stay in the original module. Do not pass a new policy object until characterization covers policy changes as their own row family.

from next_open import next_open


def first_response_deadline(created_at: datetime, severity: str) -> datetime:
    local = created_at.astimezone(TZ)
    close_inclusive = severity.lower().strip() == "urgent"

    def is_closed(d: datetime) -> bool:
        return d.weekday() >= 5 or d.date().isoformat() in HOLIDAYS

    if is_closed(local):
        return next_open(local, is_closed)

    clock = local.timetz().replace(tzinfo=None)
    if clock < CLOSE or (close_inclusive and clock == CLOSE):
        return datetime.combine(local.date(), CLOSE, tzinfo=TZ)
    return next_open(local, is_closed)
Enter fullscreen mode Exit fullscreen mode

Re-run the oracle and require a byte-identical digest. If the hash matches, the extract changed structure without changing Friday 17:00. If the hash drifts, restore the nested function and shrink the helper until the digest returns.

python characterize_sla.py
diff -u artifacts/sla_oracle.json <(python -c "import json,characterize_sla as c; print(json.dumps({'sha256': c.oracle_hash(c.oracle_payload()), 'rows': c.oracle_payload()}, indent=2))")
Enter fullscreen mode Exit fullscreen mode

Keep the candidate extract off the oracle machine

Once the oracle is local and hashed, a candidate extract can run somewhere other than a laptop. Disclosure: This article was prepared as part of MonkeyCode's product outreach. MonkeyCode's free model access and free server option can host the candidate while fixtures and hashes stay local. The model may propose the next-open function; the oracle, not the prompt, decides whether the extract is safe. Skip this hosted step when policy forbids sending even synthetic ticket timestamps to an outside service.

A practical split looks like the following command flow, with the digest computed on the machine that already holds staging exports.

# On the oracle machine, never overwrite artifacts/sla_oracle.json from a remote proposal.
python characterize_sla.py > /tmp/local.sha

# On the isolated candidate host, apply only next_open.py and re-run the same fixtures.
python characterize_sla.py > /tmp/candidate.sha

test "$(cat /tmp/local.sha)" = "$(cat /tmp/candidate.sha)"
Enter fullscreen mode Exit fullscreen mode

Do not send the holiday CSV if it includes internal shutdowns that are not already public. Synthetic rows that preserve weekday, minute, and severity are enough for the first extract.

Limitations

This workflow freezes behavior; it does not certify that the behavior is the contractual SLA. Inclusive 17:00 for urgent tickets may itself be a production bug that characterization will faithfully protect. Holiday lists drift every year, and a hash pinned in July will fail in January without a reviewed fixture update. Timezone conversion using America/New_York will not represent teams that store UTC instants and apply business hours in several regions. The next-open helper also assumes civil days, not DST folds around 09:00, so add explicit rows before extracting anything that runs through those nights.

Characterization coverage is only as wide as the CSV. A suite without Saturday creates, holiday eves, and exact 17:00 pairs will bless an extract that later moves those tickets. Agents that generate extra unit tests around the new helper can still miss the production shape if they sample round hours. Keep the oracle in review even when the new tests look thorough.

Who should not use this approach

Skip this method when legal or customer contracts require a designed SLA, not a snapshot of today's messy function. Skip it when the team cannot obtain sanitized timestamps that include Friday close and holiday eves. Skip it when the goal is a multi-region calendar rewrite, because one next-open seam will not carry that change. Skip it when nobody can explain a fixture miss in severity language, because a hash without operators is only a lock on unknown rules.

Teams that lack a staging export should collect twenty real tickets before writing helpers. Teams that already have a documented cutoff table can start from that table and still keep the hash. In both cases the extract remains one function until a second row family fails for a second reason.

After the first green extract

Merge the helper only with the oracle file and the nested cutoff still visible in the original module. Add a review checklist that names the Friday 17:00 pair and the Thursday-before-holiday row. Schedule the next seam, if any, against a new fixture family rather than against a desire for a calendar package. The messy module can stay messy everywhere the hash has not asked for a change.

Top comments (0)