The response reported a confirmed state while the source I wanted to change remained the same. Reading K-POP PULSE’s unsupported-field record led me to a new small comparator for expected values and a stored readback. It is not a patch of that API or recovered operating code.
Each website has different target fields. Supply what needs checking in its titles, states or configuration, and retain outcomes without filling unread values into success. The program is shared with a synthetic input, actual CLI checks and its application contract.
Choose target fields instead of a reassuring receipt word
The program does not decide completion from a confirmed status. Expected must contain fields actually intended to change. Comparing only an acknowledgement label can miss another value staying unchanged. Selecting the right target is a judgment grounded in the task and the website’s input contract.
In the synthetic example below, a confirmed status accompanies a source_id differing from the expectation. This is not customer information or copied event data. Choose date, address, title or another meaningful target for the site and establish that the readback identifies the same record first.
Explore the implementation
New synthetic input. Supply actual target fields and a separately inspected readback.
{
"expected": {
"source_id": "replacement",
"enabled": true
},
"readback": {
"source_id": "prior",
"enabled": true,
"status": "CONFIRMED"
}
}Keep match, mismatch and unavailable reading distinct
Matching supplied value and type produces match; an observed difference produces mismatch. A missing field or unavailable readback remains unverifiable. It is not filled with an empty string or zero to manufacture equality. A known null also differs from an absent field.
When different and unverifiable fields coexist, the overall state is mismatch while both individual outcomes remain. That identifies an actual differing value together with material still requiring inspection. Some correct fields cannot promote the remaining fields into completion.
State the strictness as part of the application contract
The new comparator distinguishes true from 1 and integer 1 from float 1.0. That is this Python program’s explicit policy, not a universal judgment of API meaning. Inspect the server’s data contract and normalize in an adapter only when the equivalence is established deliberately.
Date, offset and URL strings are not treated as equal merely because they look similar. Unrequested root readback fields are ignored, but a requested nested object is compared in full and list order matters. Extract an intended subset explicitly when that is the comparison needed.
A readback’s origin and time are separate responsibilities
No API call, write or retry happens in this program. The caller establishes which store was read when and whether its record matches the requested target. Supplying an old copy as a fresh reading cannot make a matching result proof of present application.
If a service applies changes later, its state and next reading condition need a site-specific rule. Supplied values do not prove that a request occurred or that they are current. Explain both comparison and correct evidence acquisition so another operator understands what must be connected.
Communicate outcomes with different exit codes
Supply JSON through standard input or an --input file. Match returns exit 0, mismatch exit 1, and unverifiable or invalid input exit 2; inspect the JSON state to distinguish those last outcomes. Bounds are 1–1000 expected fields, 25 levels and 1MiB CLI input. Adjust limits together with their contract and checks.
Output retains field names and states without echoing compared values. It does not automatically judge whether a field name is sensitive. Avoid secrets in public examples and logs and review actual results before sharing them. This is not whole-security or privacy certification.
A bounded comparison supports the next operating action
Twenty-six new synthetic and actual CLI checks passed. They cover absent/null values, types, nesting, ordering, rejected input and exit behavior. They do not establish that the original API still has the defect or that every write and rendered page was checked.
The implementation and ZIP provide code, example, checks and notes together. Another website can connect mismatches to another reading or corrected input and obtain missing material for unverifiable fields. I want an outcome that says what was inspected and what remains after a success-looking receipt.
Explore the implementation
New explicit-field comparison code; not an original API patch or writer.
"""Compare explicit expected JSON fields with a supplied readback; no request or write."""
import argparse,json,math,sys
from pathlib import Path
def checked_json(value,depth=0):
if depth>25:raise ValueError('JSON nesting limit')
if value is None or type(value) in (str,bool,int):return
if type(value) is float and math.isfinite(value):return
if type(value) is list:
for item in value:checked_json(item,depth+1)
return
if type(value) is dict and all(type(key) is str for key in value):
for item in value.values():checked_json(item,depth+1)
return
raise ValueError('JSON-native values required')
def same_json(a,b):
if type(a) is not type(b):return False
if type(a) is dict:return set(a)==set(b) and all(same_json(a[key],b[key]) for key in a)
if type(a) is list:return len(a)==len(b) and all(same_json(x,y) for x,y in zip(a,b))
return a==b
def check_readback(record):
if type(record) is not dict or set(record)-{'expected','readback'}:raise ValueError('Unsupported input')
expected=record.get('expected');readback=record.get('readback')
if type(expected) is not dict or not 1<=len(expected)<=1000:raise ValueError('One to1000 expected fields required')
if readback is not None and type(readback) is not dict:raise ValueError('Readback must be a record or null')
checked_json(expected);checked_json(readback);rows=[]
for name,value in expected.items():
if readback is None:state,reason='unverifiable','readback_unavailable'
elif name not in readback:state,reason='unverifiable','field_absent'
elif same_json(value,readback[name]):state,reason='match','equal'
else:state,reason='mismatch','value_or_type_differs'
rows.append({'field':name,'state':state,'reason':reason})
state='mismatch' if any(x['state']=='mismatch' for x in rows) else 'unverifiable' if any(x['state']=='unverifiable' for x in rows) else 'match'
return {'state':state,'fields':rows,'counts':{s:sum(x['state']==s for x in rows) for s in ['match','mismatch','unverifiable']}}
def main():
parser=argparse.ArgumentParser();parser.add_argument('--input',type=Path);args=parser.parse_args()
try:
if args.input:
with args.input.open('rb') as stream:raw=stream.read(1048577)
else:raw=sys.stdin.buffer.read(1048577)
if len(raw)>1048576:raise ValueError('Input limit')
result=check_readback(json.loads(raw.decode('utf-8')))
except (ValueError,TypeError,OSError,RecursionError):
print(json.dumps({'state':'invalid_input','error':'Invalid comparison contract'}));return 2
print(json.dumps(result,ensure_ascii=False));return {'match':0,'mismatch':1,'unverifiable':2}[result['state']]
if __name__=='__main__':raise SystemExit(main())