{"spec":"AIP-BS-REJECTED-PACK","version":"2026-10-03","standard":"rejected-pack-build-standard","source":"https://aipathway.com.au/explore-ai/rejected-pack-build-standard","markdown":"https://aipathway.com.au/explore-ai/rejected-pack-build-standard.md","licence":"CC BY 4.0","how_to_read":"Twelve of these thirteen 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":13,"onStub":12,"productionOnly":1,"partial":3,"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":["complete a pack with no evidence attached","bind or file","invent a missing item","skip a check in the eight"],"stays_with_person":["the binding sign-off","the named human gate","what the pack asserts"]},"job":"packs stop bouncing","skill":"rejected-pack","stub":"local.mock_pack","production":null,"product":null,"insert":null,"with_us":{"kind":"scoped_build","note":"The binding layer is the hard step and is not a product. Quoted as a scoped build."}},"with_us_next":"The binding layer is the hard step and is not a product. Quoted as a scoped build. Send the failing check id for a fixed price; do not build the live step yourself.","default_path":null,"boundary":{"never":["complete a pack with no evidence attached","bind or file","invent a missing item","skip a check in the eight"],"stays_with_person":["the binding sign-off","the named human gate","what the pack asserts"]},"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":["evidence","read_rule","cite"]},{"role":"schedule","label":"Something that runs it on time","need":"A trigger that fires on a cadence and can call an authenticated endpoint.","when_missing":"An hour. Expose one authenticated endpoint that starts the work and let anything call it, so the schedule is never welded to whoever is hosting you.","ports":["gate"]},{"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":["answer"]}],"registry":"https://aipathway.com.au/substrates.json"},"checks":[{"id":"one-graph","n":1,"title":"Facts live in one graph","statement":"Changing the trading address updates every open artefact. No second copy anywhere.","assertable":"stub","ports":["read_rule","evidence"],"stimulus":"The trading address changed once, with several open artefacts carrying it.","assertion":"Every open artefact re-derives. One stale copy is the failure, and it is the failure this whole standard exists for."},{"id":"rules-have-effective-dates","n":2,"title":"Rules have effective dates","statement":"A rule change re-derives due dates. Nobody typed a new date into a calendar.","assertable":"stub","ports":["read_rule"],"stimulus":"A rule version superseded with an effective date the runner's clock passes.","assertion":"Due dates move on their own, and the old rule remains readable with its dates."},{"id":"applicability-can-say-no","n":3,"title":"Applicability can say no","statement":"A written no is an output, not an absence.","assertable":"stub","ports":["gate","answer"],"stimulus":"A subject to which the obligation does not apply.","assertion":"A written not-applicable is produced with its reason. Silence is not an answer here."},{"id":"eight-checks-in-order","n":4,"title":"Eight checks in order","statement":"You can show the queue a pack sat in, and why.","assertable":"stub","ports":["gate","evidence"],"stimulus":"A pack failing an early check and also a later one.","assertion":"It is reported against the earlier, and its queue history is retrievable with the reason for each move."},{"id":"four-queues","n":5,"title":"Four queues, and fail does not leave","statement":"Pass, Yellow, Hold, Fail. Fail does not leave.","assertable":"stub","ports":["gate"],"stimulus":"A pack in the fail queue, then an attempt to hand it over.","assertion":"The handover is refused. A fail that can be exported anyway means the queues are labels rather than states."},{"id":"yellow-is-visible","n":6,"title":"Yellow is visible","statement":"Low-confidence fields are marked. Nothing auto-promotes them.","assertable":"stub","ports":["gate","evidence"],"stimulus":"A pack with two low-confidence extracted fields.","assertion":"Both are marked and the pack sits in Yellow. Nothing promotes it on a confidence score alone."},{"n":7,"assertable":"both","stubLimit":"The stub proves nothing leaves without a release event carrying a named person. Only the live path proves what left is what was released, rather than something regenerated after the approval.","id":"named-human-gate","title":"A named human gate","statement":"The version record has a person, a time, and what they accepted.","ports":["gate","evidence"],"stimulus":"A pack ready to leave Yellow.","assertion":"It does not move without a version record naming a person, a time and the content accepted."},{"id":"as-of-and-citations","n":8,"title":"As-of and citations","statement":"Every generated clause has a source. The pack has a date.","assertable":"stub","ports":["cite","evidence"],"stimulus":"A generated pack containing several derived clauses.","assertion":"Each clause carries its source, and the pack carries an as-of date. An uncited clause fails."},{"id":"handover-is-one-artefact","n":9,"title":"Handover is one artefact","statement":"A person who does not work here can receive the pack and not have to ask where anything is.","assertable":"both","ports":["evidence"],"stimulus":"A completed pack handed over cold.","assertion":"Everything required is inside the one artefact, with nothing resolved by a link only an insider can follow.","stubLimit":"The stub proves the artefact is self-contained by construction. Whether an outsider can actually use it is a question only a real recipient answers."},{"id":"copy-does-not-say-compliant","n":10,"title":"Copy does not say compliant","statement":"The interface says current, cited, reviewed, as-of. Never a green badge that implies more.","assertable":"stub","ports":["answer"],"stimulus":"Every user-facing string the build can produce for a passing pack.","assertion":"None asserts compliance. This is the check most likely to be regressed by somebody improving the wording, which is why it is a check rather than a style note."},{"id":"packs-are-not-training-data","n":11,"title":"Customer packs are not training data","statement":"Written in the processing terms, and enforceable in the build.","assertable":"both","ports":["evidence"],"stimulus":"A pack processed end to end.","assertion":"No pack content reaches a training or retention path the terms do not permit.","stubLimit":"The stub proves nothing in the build's own paths retains pack content. What a third-party provider does with it is a contract question, and the terms are the other half of this check."},{"id":"hard-step-is-named","n":12,"title":"The hard step is named","statement":"The binding layer is identified as such in the build, and held to every check above it.","assertable":"stub","ports":["evidence","gate"],"stimulus":"A request for which step the build treats as the binding layer.","assertion":"It is named explicitly. A build that cannot say which step is the hard one has not read the standard."},{"id":"pass-test","n":13,"title":"The pass test passes","statement":"Change the trading address once and every open artefact re-derives with its rule version and as-of date; then try to hand over a pack in the fail queue and fail to.","assertable":"production","ports":["read_rule","evidence","gate"],"stimulus":"A real address change in the live graph, and a real fail-queue pack.","assertion":"No stale address survives in any generated document, and the fail-queue handover is impossible.","stubLimit":"Deliberately unpassable on a stub. A stale second copy of a fact is something a real store accumulates over months; a stub has only what you just put in it."}]}