The Rejected Pack on Microsoft 365
One graph where each fact lives once, obligations that carry their citation, and a pack generated from bound records rather than assembled in a folder.
Used by
- Business Systems Analyst
- HSEQ Administrator
- Document Controller
- Compliance Officer
How to get this live in your business
Free. The Rejected Pack Build Standard: the objects, the checks in order, and the pass test.
Ready for
This is the parent standard, and it is the one with the most to lose from a casual implementation. Every business already has a version of this: a folder per client, per site, per job, full of documents that were correct when somebody put them there. The standard replaces the folder with a graph and a generator, and the tenant is a perfectly good place to put both.
In short
What this is
A build plan for the rejected pack standard on Microsoft 365. Six lists, two libraries, four flows, six measures.
The core rule
Change the trading address once and every pack generated afterwards is right. That property is what you are building, and a copied value destroys it.
What it does not do
It assembles a complete, current, evidenced pack and puts it in front of the person who releases it. It does not certify anything and it does not decide that an obligation is satisfied.
The hard part
The binding layer. The standard names it as the step not to hand-roll, and there is no product for it, so this is where the care goes.
Take the spec to Claude, ChatGPT or Copilot. The sentence to paste is one click away.
Want the whole thing by email?
This paper, plus the rest of the library. One click to stop them.
1. Before you start
Read the rejected pack build standard first, and its operator runbook if people rather than systems are your constraint. Shared conventions for this stack are in building the standards on Microsoft 365.
One thing to be clear about before anyone starts building. The standard names the binding layer as the step not to hand-roll, and unlike some of the others there is no product for it. That is not an oversight and this page will not pretend otherwise. It means the binding step deserves the most care, the most testing, and the refusal behaviour built first.
2. The lists, with their columns
Six lists and two libraries. The shape looks heavier than the others because it is a graph, and the weight is the point: it is what lets one edit re-derive everything downstream.
For your developer. Show the fields
Site: Packs
LIST Entity (usually one row. Sometimes a few.)
ABN Text indexed
LegalName Text
TradingName Text
TradingAddress Text CHANGE IT HERE. Nothing copies it.
LIST Locations
Entity Text indexed. lookup to Entity
LIST People
Entity Text indexed. lookup to Entity
Role Text
LIST Tickets
Person Text lookup to People
Class Choice licence | white_card | high_risk | induction
| visa
Number Text
ExpiresOn DateTime indexed
Evidence Hyperlink into the Evidence library
LIST Cover (insurance)
Entity Text lookup to Entity
Type Choice workers_comp | public_liability | vehicle
Insurer Text
PolicyNo Text
ExpiresOn DateTime indexed
Evidence Hyperlink
LIST Obligations
ObligationId Text indexed
Trigger Text what makes this apply here
Citation Text REQUIRED. The rule that says so.
Artifact Text what has to exist as a result
Cadence Text
PenaltyClass Choice your regulator's own classes
EffectiveFrom DateTime
Applicability Choice applies | does_not_apply
WhyNot Text REQUIRED when does_not_apply
Location Text lookup to Locations
LIBRARY Evidence (the documents, with what they evidence)
BoundTo Text indexed, REQUIRED. What it evidences.
LIBRARY Packs (generated output only. Never hand-edited.)
Pack Text indexed. The id PackArtifacts points at.
LIST PackArtifacts
Pack Text indexed
Obligation Text lookup to Obligations
Version Text
GeneratedAt DateTime
AsOf DateTime the facts as at this moment
Sources Text which rows produced it
Bound Boolean false blocks the packPackArtifacts is what makes a pack regenerable and auditable. Without it you have a PDF and a hope, and the question you cannot answer six months later is which version of which fact it carried.
3. Every check, and what enforces it
| The check | Enforced by | How |
|---|---|---|
| A fact lives in one place and everything re-derives | Lookups | The trading address is a column on Entity and a lookup everywhere else. Changing it once changes every pack generated afterwards, which is the whole argument of the standard. |
| An obligation carries the rule that says so | List design | Citation is required. An obligation with no citation cannot be defended when somebody asks why the artifact exists, and it is usually the one that turns out not to apply. |
| Does not apply is a written reason, not an absence | List design | Applicability plus WhyNot, both required when it does not apply. A silently missing obligation looks identical to one nobody thought of. |
| Evidence binds to the thing before the pack can close | Pack flow | The generate step refuses while any required artifact is unbound. This is the binding layer and it is the step the standard names as the hard one. |
| The pack is generated, never assembled by hand | Pack flow | Artifacts carry version, generated_at, as_of and their sources. A pack somebody built in a folder has none of those and cannot be regenerated. |
| A named person is on the gate | Approval | The pack is released by a person from a named group, recorded on the pack, not by whoever happened to run the flow. |
| Expiry is derived and surfaces before it bites | Expiry flow | Tickets, insurance and inspections all carry ExpiresOn, and the flow moves the pack out of current before the date rather than after somebody is refused on site. |
4. The four flows
For your developer. Show the fields
FLOW 1 Bind evidence
trigger a file lands in the Evidence library
logic require the obligation or ticket it evidences before
the upload can complete
set Bound on the matching PackArtifacts row
never accept a document with nothing named. An unattached
file in a library is the folder problem with extra steps.
FLOW 2 Generate the pack
trigger requested, or scheduled per location
guard REFUSE while any required artifact has Bound = false.
Write what is missing, and stop. This is the binding
layer, and a warning here is a failed implementation.
logic render each artifact from the graph, by lookup
stamp Version, GeneratedAt, AsOf and Sources
write the output to the Packs library
never read a copied value. Everything resolves through Entity.
FLOW 3 Release
trigger a generated pack awaiting release
logic request approval from the named group
record the approver on the pack
never release on behalf of whoever ran the generate
FLOW 4 Expiry
trigger scheduled, daily
logic Tickets and Cover with ExpiresOn inside the lead time
-> mark dependent packs not current, notify the owner
past ExpiresOn -> packs are not current, full stop
note run this against the graph on a clock, not at handover.
At handover, somebody is already standing at a gate.Flow 2's guard is the one sentence of this page that matters most. Everything else is plumbing around a refusal.
5. The Power BI model and its measures
For your developer. Show the fields
Unbound Artifacts =
CALCULATE ( COUNTROWS ( PackArtifacts ), PackArtifacts[Bound] = FALSE )
Packs Blocked =
CALCULATE (
DISTINCTCOUNT ( PackArtifacts[Pack] ),
PackArtifacts[Bound] = FALSE
)
Expiring 30 =
CALCULATE (
COUNTROWS ( Tickets ),
Tickets[ExpiresOn] <= TODAY () + 30,
Tickets[ExpiresOn] >= TODAY ()
)
Expired Live =
CALCULATE ( COUNTROWS ( Tickets ), Tickets[ExpiresOn] < TODAY () )
Obligations Without Citation = -- must be zero
CALCULATE ( COUNTROWS ( Obligations ), ISBLANK ( Obligations[Citation] ) )
Does Not Apply Without Reason = -- must be zero
CALCULATE (
COUNTROWS ( Obligations ),
Obligations[Applicability] = "does_not_apply",
ISBLANK ( Obligations[WhyNot] )
)
Pack Age Days =
AVERAGEX ( PackArtifacts, DATEDIFF ( PackArtifacts[AsOf], NOW (), DAY ) )The two must-be-zero measures are the cheapest audit in this library. An obligation with no citation and a does-not-apply with no reason are both the same failure: somebody decided something and left no way to check it.
6. The order to build it in
- Build Entity, Locations and People first, with one row each. The graph before anything that reads it.
- Add Tickets and Cover. Index ExpiresOn now.
- Load Obligations for one location, with at least one marked does not apply so the WhyNot requirement is exercised.
- Build Flow 1 and confirm a file cannot be uploaded without naming what it evidences.
- Build Flow 2 with the refusal first, before any rendering. Prove it refuses, then teach it to generate.
- Run the pass test: change the trading address and regenerate.
- Build Flow 3, then Flow 4.
- Connect Power BI. The two must-be-zero measures go on the front page.
7. Four traps specific to this build
A pack as a folder of PDFs
This is what everybody already has and it is precisely what the standard replaces. A folder cannot tell you which version of a fact each document carries, cannot be regenerated after the address changes, and quietly becomes stale one document at a time.
Re-typing the entity details onto each pack
The moment a fact exists in two places, one of them is wrong and it is usually the one that went out. Everything that names the entity is a lookup, and the pack template reads the lookup rather than a copied value.
Treating unbound as a warning
If the generate step runs and posts a note about missing evidence, packs go out incomplete and the note is the thing nobody reads. Unbound must stop the generate. That is the difference between this standard and a checklist.
Expiry checked when the pack is requested
By then it is too late: somebody is at a gate. Run expiry on a schedule against the graph, and let the pack's currency be a property of the facts rather than a question asked at handover.
8. Where the automation stops
- Certifying anything, or signing on behalf of a licensed person.
- Deciding that an obligation does not apply. A flow can require the reason; it cannot supply it.
- Releasing a pack. A named person from a named group, recorded.
- Deciding an expired ticket is close enough to let somebody on site.
- The binding layer's judgement calls. There is no product for this step and nothing here pretends there is.
The pass test. Two checks, both on test data. First, mark one required artifact unbound and request a pack: the generate must refuse and name what is missing, and no file may appear in the Packs library. Second, change TradingAddress on Entity and regenerate a pack that was correct before: the new pack must carry the new address without anyone editing a template, and the old pack must still show the old one with its own AsOf. If the first produces a pack with a warning attached, you have built a checklist. If the second needs a template edited, a fact lives in two places and you have not built the graph the standard is about.