{"spec":"AIP-BS-KNOWLEDGE-BASE","version":"2026-10-03","standard":"knowledge-base-build-standard","source":"https://aipathway.com.au/explore-ai/knowledge-base-build-standard","markdown":"https://aipathway.com.au/explore-ai/knowledge-base-build-standard.md","licence":"CC BY 4.0","how_to_read":"Eleven 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 runs against your own live systems. One is not a software check at all: it asks what you measured before you started.","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; runs against your own live systems (see with_us_next)","evidence_required":"not a software check. Attach what proves it"},"tally":{"total":13,"onStub":11,"productionOnly":1,"partial":0,"preconditions":1},"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":["index a file that is not on the register","name a team as an owner","put customer material in the shared index","return a composed answer from search","hand the graph a source the register does not hold","promote an entry to the graph with no person in promoted_by"],"stays_with_person":["owning a source, and answering for it when it moves","deciding which copy is canonical","closing a gap for a source that cannot be found","who may read customer material and for how long","promoting a register entry to the graph"]},"job":"everything the business relies on, in one place, with a name on it","skill":"knowledge-base","stub":"local.mock_drive","production":null,"product":null,"insert":null,"with_us":{"kind":"own_systems","note":"No hosted step. The production check runs over the business's real drive and mailbox with its real owners. The watch is the part not to hand-roll: a scheduled re-fetch and checksum compare of every source, with the owner told when it moves. It is a schedule and a table, not a product."}},"with_us_next":"No hosted step. The production check runs over the business's real drive and mailbox with its real owners. The watch is the part not to hand-roll: a scheduled re-fetch and checksum compare of every source, with the owner told when it moves. It is a schedule and a table, not a product. There is nothing to buy: your build does this step on the business's own systems. No production run is offered yet, because the live port map is not published, so do not run AIPATHWAY_ENV=production. Run the pass test by hand on the real systems and attach the evidence.","default_path":null,"boundary":{"never":["index a file that is not on the register","name a team as an owner","put customer material in the shared index","return a composed answer from search","hand the graph a source the register does not hold","promote an entry to the graph with no person in promoted_by"],"stays_with_person":["owning a source, and answering for it when it moves","deciding which copy is canonical","closing a gap for a source that cannot be found","who may read customer material and for how long","promoting a register entry to the graph"]},"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_rule","read_file","raise_task","write_node","read_register","write_register","index_passage","search_index"]},{"role":"send","label":"Something that sends","need":"Email or SMS from a domain the recipient recognises, with delivery visible enough to tell a bounce from a silence.","when_missing":"An hour for the wiring, longer for the DNS. Sending from a domain you do not own is the single fastest way into a spam folder.","ports":["notify"]}],"registry":"https://aipathway.com.au/substrates.json"},"checks":[{"id":"register-before-index","n":1,"title":"Every source is on the register before anything is indexed","statement":"A file is registered with a title, a location and an owner before a passage from it is chunked or embedded. Indexing an unregistered file fails.","assertable":"stub","ports":["read_file","write_register","index_passage"],"stimulus":"A drive holding six files of four kinds, two of them copies of each other.","assertion":"Every indexed passage names a register id, and that register entry was written earlier in the trace than the passage. A passage with no register id, or one written before its source was registered, fails."},{"id":"one-canonical-copy","n":2,"title":"Duplicates resolve to one canonical copy, and only the canonical is indexed","statement":"Two copies of the same source are one register entry with the others marked duplicate_of. The index holds the canonical copy once.","assertable":"stub","ports":["read_file","write_register","index_passage"],"stimulus":"The same manual saved twice under different names, one of them older.","assertion":"One canonical entry, one duplicate pointing at it, and no passage indexed from the duplicate. Two canonical entries for one checksum, or passages from both copies, fails."},{"id":"owner-is-a-person","n":3,"title":"Every source has a named owner, and a team is not an owner","statement":"The owner is the person who is asked when the source moves or goes missing. \"Operations\" cannot be asked anything.","assertable":"stub","ports":["write_register","read_register"],"stimulus":"The drive above, with one file whose obvious owner is a department.","assertion":"Every register entry carries an owner that is a person. An entry whose owner is a team name, or is empty, fails."},{"id":"edition-and-checksum-on-arrival","n":4,"title":"Retrieved date, checksum and edition are recorded when the source arrives","statement":"A source without a checksum cannot be watched. One without an edition, where the issuer publishes one, cannot be handed to the graph.","assertable":"stub","ports":["write_register"],"stimulus":"An issued instrument with an edition on its cover, and an internal template with none.","assertion":"Both entries carry retrieved_at and a checksum. The instrument carries its edition. A registered source with no checksum fails."},{"id":"customer-material-quarantined","n":5,"title":"Customer material is registered as such, restricted, and kept out of the shared index","statement":"Client files, interviews and emails are inventoried with kind customer_material and an access list. They are never chunked into the search everyone uses.","assertable":"stub","ports":["write_register","index_passage"],"stimulus":"A client interview transcript in the same folder as the policy manual.","assertion":"The transcript is on the register with kind customer_material and a restricted access list, and no passage from it is in the shared index. A customer file indexed beside the policy fails."},{"id":"locators-are-replayable","n":6,"title":"Every indexed passage names its source and a locator that can be opened","statement":"Page and section, offsets in a stable file version, or seconds on a recording. \"Chunk 47\" is not a locator.","assertable":"stub","ports":["index_passage"],"stimulus":"Passages cut from a paged document and from a recording.","assertion":"Every passage carries a register id and a locator with a page, a section, an offset or a timestamp. A passage whose only identity is a chunk number fails."},{"id":"search-finds-never-answers","n":7,"title":"Search returns passages with their source and locator, and composes nothing","statement":"A query returns what was found and where. It does not return a paragraph the model wrote. Answering is the Cited Answer standard, over the graph.","assertable":"stub","ports":["search_index"],"stimulus":"A question the material covers, asked of the search.","assertion":"The result is a list of passages, each with a register id and a locator, and no composed text. A search that returns an answer paragraph fails."},{"id":"missing-is-a-gap-with-an-owner","n":8,"title":"A source that should exist and cannot be found is a gap with an owner and a date","statement":"The current edition of an instrument the business relies on, not on the drive, is not a blank row. It is a task for a person.","assertable":"stub","ports":["read_register","raise_task"],"stimulus":"A register that expects the current tenancy legislation and a drive that holds only the previous edition.","assertion":"A gap exists for the missing edition, with an owner and a due date. A register that reports complete, or a gap with no owner, fails."},{"id":"watch-on-a-schedule","n":9,"title":"Every source on the drive is re-fetched on a schedule, and a changed checksum reaches its owner","statement":"The watch runs whether or not anything changed. When a checksum moves, the register records the new one, marks the old copy superseded, and the owner is told the same run. A source held only by the issuer gets a recheck task to its owner on the same schedule, and the confirmation is recorded.","assertable":"stub","ports":["read_file","write_register","notify"],"stimulus":"A scheduled run over the register, then one source replaced on the drive, then the next run.","assertion":"Both runs read every source. After the change, the entry carries the new checksum, the previous copy is marked superseded, and the owner has a notification naming the source. A change with no notification, or a run that read only some sources, fails."},{"id":"retention-follows-kind","n":10,"title":"Retention and access follow the kind of source","statement":"An issued instrument is kept with every edition. Customer material carries an expiry and an access list. The kind decides, not the folder it was found in.","assertable":"stub","ports":["write_register","read_register"],"stimulus":"The register above, read back.","assertion":"Every customer_material entry carries an expiry and an access list. Every instrument entry keeps its superseded editions retrievable. A customer file with no expiry fails."},{"id":"handover-carries-the-register","n":11,"title":"A source reaches the graph only from the register, carrying its id, edition, checksum and locator scheme","statement":"The Knowledge Graph standard registers a source as an instrument. That instrument is this register entry, not a fresh upload. A graph source with no register id has skipped this standard.","assertable":"stub","ports":["read_register","write_node"],"stimulus":"A registered instrument promoted to the graph.","assertion":"The graph source carries the register id, the edition, the checksum and the locator scheme from the entry. A promotion of an unregistered file, or one whose checksum differs from the register, fails."},{"id":"survives-the-builder","n":12,"title":"It survives the builder","statement":"Someone other than the builder can explain what it does, and it runs on an account the business owns.","assertable":"precondition","ports":["read_rule"],"stimulus":"No stimulus. The builder names who else can explain it and whose account the register, the index and the watch runs on.","assertion":"The runner reports what was declared and never scores it green on its own say-so.","stubLimit":"Not a runtime property. Software cannot prove a second person understands it, and outliving its author is precisely what is being asked about."},{"id":"pass-test","n":13,"title":"The pass test passes","statement":"On the business's real drive: every source registered with a person, one duplicate found and resolved, one client file quarantined, a real edition change caught by the watch within a cycle, and a search that returns locators the owner can open.","assertable":"production","ports":["read_file","write_register","search_index"],"stimulus":"The real shared drive and mailbox, the real owners, and one instrument the issuer actually replaces during the trial.","assertion":"The register matches what is on the drive, the duplicate is one entry, the client file is not searchable by the wrong person, the replaced edition is on the register with its owner notified, and a person can open every locator a search returns.","stubLimit":"Deliberately unpassable on a stub. A stub drive holds what the runner put there and changes when told. Only the real drive proves the inventory is complete, and only a real issuer replacing a real edition proves the watch caught it."}]}