{"spec":"AIP-BS-FIRE-SERVICE-PACK-STANDARD","version":"2026-10-03","standard":"fire-service-pack-standard","source":"https://aipathway.com.au/explore-ai/fire-service-pack-standard","markdown":"https://aipathway.com.au/explore-ai/fire-service-pack-standard.md","licence":"CC BY 4.0","how_to_read":"Eleven of these twelve checks run on your own machine, against the stub, before you talk to anybody. The last one is a live tenant, and that one is quoted as a scoped build.","verdicts":{"pass":"asserted green here","fail":"asserted red here. This is a fixture: it names the check to price","shape_only":"shape holds on the stub, truth needs the live provider","with_us":"cannot be proved on the stub; the live step is quoted as a scoped build (see with_us_next)","evidence_required":"not a software check. Attach what proves it"},"tally":{"total":12,"onStub":11,"productionOnly":1,"partial":0,"preconditions":0},"envelope_version":"1.0","port_shape":{"read_ledger":{"verb":"read","subject":"ledger"},"read_job":{"verb":"read","subject":"job"},"read_asset":{"verb":"read","subject":"asset"},"read_rule":{"verb":"read","subject":"rule"},"read_contacts":{"verb":"read","subject":"contacts"},"read_segment":{"verb":"read","subject":"segment"},"resolve_address":{"verb":"read","subject":"address"},"write_job":{"verb":"write","subject":"job"},"read_pricebook":{"verb":"read","subject":"pricebook"},"draft_quote":{"verb":"write","subject":"quote"},"write_invoice":{"verb":"write","subject":"invoice"},"write_ledger":{"verb":"write","subject":"ledger"},"record_promise":{"verb":"write","subject":"promise"},"record_service":{"verb":"write","subject":"service_record"},"release_payment":{"verb":"write","subject":"payment"},"talk":{"verb":"say","subject":"turn"},"disclose":{"verb":"say","subject":"disclosure"},"send_sms":{"verb":"say","subject":"sms"},"notify":{"verb":"say","subject":"alert"},"escalate":{"verb":"say","subject":"handoff"},"issue_notice":{"verb":"say","subject":"notice"},"answer":{"verb":"say","subject":"answer"},"publish_report":{"verb":"say","subject":"report"},"record_consent":{"verb":"write","subject":"consent"},"read_file":{"verb":"read","subject":"file"},"write_file":{"verb":"write","subject":"file"},"raise_task":{"verb":"write","subject":"task"},"read_node":{"verb":"read","subject":"node"},"write_node":{"verb":"write","subject":"node"},"read_register":{"verb":"read","subject":"register"},"write_register":{"verb":"write","subject":"register"},"index_passage":{"verb":"attach","subject":"passage"},"search_index":{"verb":"read","subject":"index"},"read_inbox":{"verb":"read","subject":"message"},"file_message":{"verb":"attach","subject":"message"},"write_order":{"verb":"write","subject":"order"},"read_quote":{"verb":"read","subject":"quote"},"write_log":{"verb":"write","subject":"log"},"evidence":{"verb":"attach","subject":"evidence"},"cite":{"verb":"attach","subject":"citation"},"rank":{"verb":"decide","subject":"order"},"gate":{"verb":"decide","subject":"gate"}},"provider":{"boundary":{"never":["record a test without the asset and the photograph of the tag","treat unbound as pass","certify","file a pack with a missing item"],"stays_with_person":["signing","attesting the annual statement","deciding competency","the named human gate"]},"job":"a fire service pack that cannot be filed without evidence","skill":"fire-service-pack-standard","stub":"local.mock_asset_register","production":null,"product":null,"insert":null,"with_us":{"kind":"scoped_build","note":"No hosted product. The binding layer is quoted as a scoped build, run against the asset register and document store already in use."}},"with_us_next":"No hosted product. The binding layer is quoted as a scoped build, run against the asset register and document store already in use. Send the failing check id for a fixed price; do not build the live step yourself.","default_path":null,"boundary":{"never":["record a test without the asset and the photograph of the tag","treat unbound as pass","certify","file a pack with a missing item"],"stays_with_person":["signing","attesting the annual statement","deciding competency","the named human gate"]},"substrate":{"how_to_read":"These are roles, not products. Work out which you already have by matching `providers[].detect` against the repository, then build or add only the gap. No check asserts against a vendor, so any substrate that answers the role passes the same checks.","requires":[{"role":"record","label":"Somewhere the book lives","need":"Durable storage that the workflow owns the write path to, keyed so the same record can be found twice.","when_missing":"Half a day. Any Postgres will do and the free tiers are ample at this size. The trap is not the database, it is letting people edit around the app that is supposed to own the value.","ports":["read_asset","record_service","evidence","read_rule"]},{"role":"surface","label":"Something a person opens","need":"A view of the book that whoever does this job can read and act on without asking a developer.","when_missing":"Start at tier 0 and stop there until the business asks for more. The cheapest surface is not a screen, it is a scheduled email carrying the list, and for one person doing this job that is not a compromise, it is the right answer. On Microsoft 365 or Workspace you can skip straight past this: a list and a sheet are already what people open. Build upward only when two people need the same list at the same time.","tiers":[{"tier":0,"label":"A scheduled digest carrying the list","cost":"About an hour. Needs nothing you do not already have.","satisfiedBy":"send","whenYouNeedIt":"One person does this job. They want to know what is waiting when they sit down, and they act on it from their inbox."},{"tier":1,"label":"A read-only page showing the book","cost":"An afternoon. One query and one table.","whenYouNeedIt":"Somebody needs to look mid-day without waiting for tomorrow's digest, or to answer a customer on the phone."},{"tier":2,"label":"Editable rows, a queue and a log","cost":"A day or two with a coding agent, which is what agents are best at. It is bounded work: the fields are the schema, the queue is whatever escalate hands off, the log is the trace.","whenYouNeedIt":"More than one person shares the book and they need to correct it without treading on each other, and you need to see afterwards who changed what."}],"ports":["escalate"]}],"registry":"https://aipathway.com.au/substrates.json"},"checks":[{"id":"identity-first","n":1,"title":"Identity before everything","statement":"A record cannot be created without resolving to exactly one asset. An unresolvable asset is a finding, not a note on the job.","assertable":"stub","ports":["read_asset","record_service"],"stimulus":"Three visits: one to a known tag, one to a tag that matches nothing, one to a tag that matches two assets.","assertion":"Only the first produces a record. The other two produce findings, and neither writes a service record."},{"id":"discharges-an-obligation","n":2,"title":"The visit discharges something","statement":"Every record names the obligation it satisfies. A visit that discharges nothing cannot be counted as coverage.","assertable":"stub","ports":["read_asset","record_service"],"stimulus":"A visit to an asset carrying two live obligations, naming neither.","assertion":"The record is refused or held rather than stored with a null obligation, and coverage does not move."},{"id":"result-recorded-not-computed","n":3,"title":"Result is recorded, never computed","statement":"Pass, defect or isolated is entered by the competent person who attended. Nothing in the system derives it from the evidence.","assertable":"stub","ports":["record_service"],"stimulus":"A visit where every reading is within range but the attending person records a defect.","assertion":"The stored result is the defect the person entered. No derived value overrides it."},{"id":"evidence-per-class","n":4,"title":"Evidence is a property of the class","statement":"Required evidence differs by asset class, and readings are stored as numbers in fields rather than photographs of gauges.","assertable":"stub","ports":["evidence","record_service"],"stimulus":"One portable item, one system with readings, one passive item, each visited with the wrong evidence for its class.","assertion":"Each is held for the evidence its own class requires, and a reading supplied as an image is not accepted as a reading."},{"id":"baseline-absence-reportable","n":5,"title":"Baseline absence is reportable","statement":"Where baseline data was required and unavailable, the record stores that as a non-conformance rather than leaving the field blank.","assertable":"stub","ports":["evidence","record_service"],"stimulus":"A visit to an asset with no baseline on file.","assertion":"A non-conformance is stored naming the missing baseline. An empty field is not accepted, because an empty field and a missing baseline are different facts and only one is reportable."},{"id":"electrical-blocks-close","n":6,"title":"Electrical work blocks the close","statement":"A missing certificate or test sheet stops the job closing. It never raises a reminder and lets the job through.","assertable":"stub","ports":["evidence","record_service"],"stimulus":"A visit involving electrical work, closed without attaching a certificate.","assertion":"The close is refused. A reminder without a refusal fails this check."},{"id":"defects-coded","n":7,"title":"Defects are coded","statement":"Defects come from a closed list with a named owner for the next action, so they can be counted and chased. Free text is a description, not a defect.","assertable":"stub","ports":["record_service"],"stimulus":"A defect entered as a paragraph with no code and no owner.","assertion":"It is refused or held. Every stored defect carries a code from the list and a named owner."},{"id":"isolation-has-revisit","n":8,"title":"Isolation carries a revisit date","statement":"An isolation records who authorised it, why, and the date it must be revisited, and it escalates when that date passes.","assertable":"stub","ports":["record_service","escalate"],"stimulus":"An isolation with no revisit date, then a second with a date the runner's clock moves past.","assertion":"The first is refused. The second escalates on the day it lapses, and does not clear itself."},{"id":"unbound-is-visible","n":9,"title":"Unbound is a queue you can see","statement":"Work marked done with required evidence missing sits in its own queue with its age on a chart. It is never reported as a pass.","assertable":"stub","ports":["record_service","evidence"],"stimulus":"A visit marked complete with the tag photograph missing.","assertion":"The record lands in unbound, is absent from the pass count, and carries an age. A build with no unbound queue fails here even though nothing errored, which is the point of the check."},{"id":"documents-from-the-record","n":10,"title":"Documents are generated from the record","statement":"Anything client-facing is derived from the bound record, never assembled from a template on somebody's desktop.","assertable":"stub","ports":["record_service","evidence"],"stimulus":"A client-facing document requested for an asset whose record was since corrected.","assertion":"The document carries the corrected values, because it is derived at request time."},{"id":"jurisdiction-is-data","n":11,"title":"Jurisdiction is data","statement":"Retention period and who may attest are dated, cited values per state, not constants in the code.","assertable":"stub","ports":["read_rule","read_asset"],"stimulus":"The same asset requested as a Queensland site and as a Victorian one.","assertion":"Retention and the person who may attest differ between the two. A single hard-coded value fails, because it is wrong in at least one state."},{"id":"pass-test","n":12,"title":"The pass test passes","statement":"The signature stays with a person. The build assembles and presents the pack; it does not certify, decide compliance, or produce a certificate.","assertable":"production","ports":["record_service","evidence","escalate"],"stimulus":"A complete pack produced for a real asset and handed to the person who attests, on a live register.","assertion":"The pack is complete and produced within the jurisdiction's window, and nothing in the flow issues or implies a certificate.","stubLimit":"A stub can prove no certificate-shaped output exists. Only a live register proves the pack can actually be produced on demand from the system the business really runs, which is the thing an auditor asks for."}]}