Skip to content
CogniSkill

LESSON 1 OF 4

Turn an automation request into a precise contract

Practice notesBooks for further learning

Define the operation before writing the loop

“Keep the inventories in sync” is not a specification. It could mean reporting differences, editing a directory, deleting unobserved devices or assigning owners automatically. Those operations have different evidence requirements and consequences. Our first automation does one narrowly stated job: compare two already exported snapshots and produce findings for human review.

Write the input, decision and output contract in your notes. Inputs are a registered inventory CSV, an observed inventory CSV and one collection manifest for each. The decision is a comparison by stable asset identity. Outputs are a findings CSV and a summary containing population counts and source hashes. Side effects are limited to a newly created output directory. Existing input files and existing output directories must remain unchanged.

A REGISTER_ONLY result means the asset identifier is present in the register and absent from the supplied observed export. It does not establish that the device was destroyed, disconnected or never existed. An OBSERVED_ONLY result means the reverse difference. It does not establish that the device is unauthorized. The names deliberately describe the evidence rather than asserting a lifecycle decision.

This distinction prevents an attractive automation demo from becoming an unsafe retirement rule. A collector could miss a whole network segment, a permission scope could hide devices, or an export could have stopped after its first page. A successful file read does not prove a complete population.

Give every record a stable identity

A display name such as Ana's laptop is useful for people but poor for reconciliation. Names change, and more than one device can have the same name. The fixture uses a source-defined asset identifier with the format A-001. In this fictional system the identifier is case-insensitive; leading/trailing whitespace is not meaningful. Therefore a-001 and A-001 represent the same identity after normalization.

That policy is specific to this system. Do not automatically uppercase real serial numbers, user names or arbitrary database keys without checking their contract. The owner field here is a stable identifier in the form u101 and is case-sensitive. It is not a display name or an email address. Site codes are the enumerated values HQ and BRANCH; letter case is normalized for those codes.

Normalization makes comparison consistent. Validation establishes whether a normalized value belongs to the accepted domain. Uppercasing unknown does not turn it into a valid asset identifier. Converting a missing owner into an empty string does not establish a valid owner. This program rejects either problem before issuing any inventory findings.

Prepare the four input files

Save the registered export as register.csv:

asset_id,owner_id,site
A-001,u101,HQ
A-002,u102,HQ
A-003,u103,BRANCH
A-004,u104,HQ

Save the observed export as observed.csv. Keep the spaces around its first asset identifier for the normalization exercise:

asset_id,owner_id,site
 a-001 ,u101,hq
A-002,u999,BRANCH
A-003,u103,BRANCH
A-005,u105,HQ

Save the registered manifest as register-manifest.json:

{"complete":true,"row_count":4,"collected_at":"2026-10-01T09:00:00Z"}

Save the observed manifest as observed-manifest.json:

{"complete":true,"row_count":4,"collected_at":"2026-10-01T09:05:00Z"}

Duplicate manifest properties are rejected rather than allowing a later completion or count value to hide an earlier value. The manifests record a declared complete export, its expected number of parsed data records and its collection timestamp. true is a JSON Boolean; the word "true" in quotes is a string and does not satisfy this contract. row_count is an integer. A decimal, a negative number or a Boolean is not accepted as a row count. The program checks the exact type because Python's Boolean type has an integer relationship that can surprise a loose isinstance check.

Both timestamps contain a time-zone indication. An offset-free value cannot be reliably compared across collectors in different time zones. The code converts valid aware timestamps to UTC while preserving their distinct collection moments. It does not treat the report generation time as the time at which every asset was observed.

Predict the result manually

Make a five-row table of identities before running any code. A-001 and A-003 appear in both sources with matching fields after normalization. A-002 appears in both with two field differences: owner and site. A-004 appears only in the register. A-005 appears only in the observed export.

There should be four finding rows, but only three assets with findings. There are two field rows for A-002, one register-only row and one observed-only row. A dashboard that calls all four rows “affected devices” would overstate the device count. Decide the grain of each output measure before adding totals or percentages.

Check your population reconciliation

Registered assets: 4. Observed assets: 4. Shared assets: 3. Matching shared assets: 2. Mismatching shared assets: 1. Register-only assets: 1. Observed-only assets: 1. Field-mismatch rows: 2. Total finding rows: 4. Registered = shared + register-only; observed = shared + observed-only.

Checkpoint challenge

Change the observed first row to A-001,u101,HQ in a copy of the file. Predict which finding rows should change. None should change: the edit removes presentation differences that normalization already ignores. The raw file hash should change because the source bytes changed. Business result equality and byte-for-byte source equality are different claims.

Now change the first owner to U101. Predict whether the program should silently lowercase it. It should reject the row under the chosen case-sensitive owner contract. Changing the contract requires a documented decision and new tests, rather than a convenience fix inside a parser.

Reasoning model

An automation run should have a defined input set, transformation and commit point. Idempotency means repeating the same intended operation does not create additional unintended effects; it does not mean ignoring every duplicate-looking row. Choose a stable identity and document how changed content is handled. Stage output before replacing a destination, and never report success until the final write and validation complete.

Official reference for further study

YOUR NEXT STEP

Keep building your skills

No directly related CogniSkill book is mapped to this course yet. Continue with the free learning, or compare the publishing catalogue by your next goal.

Explore books by topic and goal →

Sign in to save lesson completion. Reading position is separate from completion.

Practice notes — your working space

Save predictions, outputs and explanations as you work. Notes stay on this browser, not your account; people sharing this browser can access them. Avoid passwords and sensitive data. Export to keep a portable copy, or clear your notes before leaving a shared device.

How was this lesson?

Help us improve this lesson.