DEV Community

Dakota Huang
Dakota Huang

Posted on

One Star Alias Moves Only After Grant Rows Freeze

One Star Alias Moves Only After Grant Rows Freeze

A permission blob should not change during a small extract. Freeze twelve grant tuples before you touch the helper. Move only the star-alias branch after those rows match.

This plan targets one messy function in a legacy auth helper. It does not rewrite the whole permission module. The safe unit is one alias rule with a frozen oracle.

Why the blob is the contract

Callers read a sorted tuple of grant strings. They do not read branch names inside the helper. A cleanup that reorders tokens can deny a valid call.

The helper mixes comma splits, case folds, and star aliases. Those rules grew in one function over several years. This change lifts one alias and leaves the rest.

What the twelve rows lock

Twelve fixture rows define the oracle for this extract. Each row has an input string and an expected tuple. The expected tuple is observed output, not a guessed spec.

Treat these rows as unexecuted examples until you run them. Do not invent production counts from this sample. Replace any tuple that disagrees with the live helper.

1. Capture outputs before the edit

Point a tiny script at the current helper. Print each input beside the tuple the helper returns. Save that printout before you rename any symbol.

# Proposal only. Unexecuted until expand_grants is the real helper.

SAMPLES = [
    "read:orders",
    "orders.*",
    "read:orders,write:orders",
    "write:orders,read:orders",
    "orders.*,read:orders",
    "",
    "  orders.*  ",
    "read:orders,,write:orders",
    "READ:orders",
    "orders.* , billing.*",
    "billing.*",
    "unknown:thing",
]

def capture(expand_grants):
    for raw in SAMPLES:
        print(repr(raw), "=>", repr(expand_grants(raw)))
Enter fullscreen mode Exit fullscreen mode

Run capture on the branch you intend to change. Paste the printed tuples into the test file. Do not hand-edit a tuple to look cleaner.

2. Encode the oracle as subtests

Each subtest binds one input to one tuple. A failure names the raw string in the report. The suite does not inspect private helpers or logs.

import unittest

# from auth_legacy import expand_grants  # example binding, not a real module
# CASES must be filled from capture() output, not from memory.

CASES = []  # paste observed pairs here before the extract

class GrantOracleTest(unittest.TestCase):
    def test_frozen_grant_tuples(self):
        for raw, expected in CASES:
            with self.subTest(raw=raw):
                self.assertEqual(expand_grants(raw), expected)

if __name__ == "__main__":
    unittest.main()
Enter fullscreen mode Exit fullscreen mode

Run the suite with the standard library only. Keep third-party plugins out of this comparison run. A plugin can reorder output and hide a real miss.

python -m unittest grant_oracle_test.py -v
Enter fullscreen mode Exit fullscreen mode

Stop when any subtest is red before the extract. A red row means the paste is wrong. Fix the fixture, not the helper, at this step.

3. Mark one branch as movable

Only the orders star alias is in scope for the move. Billing stars, case folds, and empty tokens stay put. Those paths remain inside the legacy function for now.

Input shape Movable now Why
orders.* yes the alias being lifted
orders.* plus an explicit grant yes same alias, mixed input
billing.* no other prefix, later change
READ:orders no case fold is untouched
doubled comma no empty token rule stays
unknown:thing no passthrough stays

Six rows exercise the alias you will move. Six rows lock behavior this patch must not touch. Use that split when you read the diff.

4. Lift the alias, keep the call site

Move the orders star mapping into one function. Keep the call in the same place in the loop. Do not sort twice or change token splitting here.

def orders_star_grants():
    # Smallest extract. Unexecuted until the oracle is green.
    return ("read:orders", "write:orders")

def expand_grants(raw):
    # Pseudocode. Bind these names to the legacy body.
    parts = split_and_normalize(raw)
    grants = []
    for part in parts:
        if part == "orders.*":
            grants.extend(orders_star_grants())
        else:
            grants.extend(existing_branch(part))
    return tuple(sorted(set(grants)))
Enter fullscreen mode Exit fullscreen mode

The snippet is pseudocode around an unknown legacy body. Wire it to real names in your repo. Do not copy the split logic from this page.

5. Re-run the same command

The unittest command stays identical after the extract. A new flag or file would weaken the comparison. Only pass or fail on the twelve rows matters here.

python -m unittest grant_oracle_test.py -v
Enter fullscreen mode Exit fullscreen mode

A green run means the tuples still match. It does not prove every caller is safe. Add a caller fixture if one path bypasses the helper.

6. Read the diff with a hard boundary

Open the patch and list every touched symbol. You should see the new function and one call. Any other hunk is out of scope for this commit.

git diff --stat -- auth_legacy.py grant_oracle_test.py
Enter fullscreen mode Exit fullscreen mode

The stat line should stay within the two example paths. A third path means this extract grew past the gate.

If formatting noise appears, drop it from the patch. If a rename touches billing, revert that hunk. Keep the commit small enough to review in one pass.

7. Decide with the row split

Pass the change only when alias rows and guard rows agree. Fail the change when a guard row drifts. Hold the change when a row was never captured.

Do not update an expected tuple to force green. That edit hides the behavior change you meant to prevent. Capture again only if the pre-change paste was incomplete.

Where drafts can help, and where they stop

You can draft the twelve assertions before you touch the branch. MonkeyCode's free model access can propose the test scaffold from the fixture table. Disclosure: This article was prepared as part of MonkeyCode's product outreach.

Use the free server option to run unittest in a clean checkout. Treat both options as conveniences, not as proof. The model may invent a grant that your helper never emitted.

Review every expected tuple against a local run. Reject a draft that changes more than the star-alias function. Reject a draft that edits case folding in the same patch.

Ask the draft for a test file, not for a new permission model. Ask it to preserve odd outputs, including empty tuples. Discard any rewrite that deletes the legacy loop.

Failure rules you can apply today

Keep the extract if all twelve subtests pass. Revert the patch if any untouched row changes. Revert if the new function is called for billing.

Revert if sort order flips for a mixed row. Do not widen the patch to clean up adjacent branches. That cleanup belongs in a later oracle-backed change.

Limits you should state in review

Characterization rows preserve current behavior, including known bugs. A frozen typo stays a typo until a separate change. Twelve rows do not cover unicode spaces or repeated stars.

A remote runner may differ from your production image. Do not treat a remote green run as a release gate. Re-run the same file on the build agent you already trust.

No duration, quota, or hardware claim belongs in this workflow. Confirm current free-tier terms in the product docs before you rely on them. Product pages change, and this note does not freeze those terms.

Who should not use this gate

Skip it during an active incident with a known bad deploy. Skip it if grants come from a remote policy service. Skip it if the helper reads the clock or a random source.

Skip it if you lack a way to capture current outputs. A team that wants a new permission model needs a spec, not a freeze. This method will faithfully lock the old model in place.

Review checklist before merge

First, store twelve observed tuples before the edit starts. Second, touch only the new alias function and its call. Third, keep untouched rows passing without edited expectations.

Fourth, keep the unittest command the same before and after. Fifth, compare model-written rows with local output yourself. Fail the review if any of those five checks slip.

If the patch touches extra symbols, split it before review. If a guard row fails, restore the branch from git. If nobody compared the draft, write the assertions yourself.

The next extract can be the billing star, but only with the same freeze. Do not stack both aliases into this commit. Repeat the capture step so the next oracle is fresh.

Open the free server option and run this same unittest file. Keep the fixture file unchanged between the two runs. Stop if the remote result disagrees with your local oracle.

Top comments (0)