[{"data":1,"prerenderedAt":1570},["ShallowReactive",2],{"docs-sections":3,"docs-page-\u002Fdocs\u002Fbusiness-rules":124},[4,9,13,17,21,25,30,34,38,42,46,50,54,58,62,66,71,75,79,83,88,92,96,100,104,108,112,116,120],{"path":5,"title":6,"description":7,"group":8},"\u002Fdocs","Introduction","pdd-kit brings Product-Driven Development to coding agents through a Git-tracked Product Model and an automatic verification loop.","Get started",{"path":10,"title":11,"description":12,"group":8},"\u002Fdocs\u002Finstallation","Installation","Install the pdd-kit skills into your coding agent at project or global scope.",{"path":14,"title":15,"description":16,"group":8},"\u002Fdocs\u002Ffrom-your-repo","From your repo","Map what an existing repository already does into a Product Model, review it, then check the code against it.",{"path":18,"title":19,"description":20,"group":8},"\u002Fdocs\u002Ffrom-an-idea","From an idea","Decide what a new product does, approve its Product Model, then ask your agent to implement it while verify checks each part.",{"path":22,"title":23,"description":24,"group":8},"\u002Fdocs\u002Ffrom-a-blueprint","From a Blueprint","Pull a reviewed Product Model for a common kind of product instead of starting blank, adapt it if needed, then ask your agent to implement it.",{"path":26,"title":27,"description":28,"group":29},"\u002Fdocs\u002Fproduct-model","Model overview","The Product Model in five minutes (what the product-model\u002F folder holds, what each resource type is for, and how to tell them apart).","Product Model",{"path":31,"title":32,"description":33,"group":29},"\u002Fdocs\u002Fproduct","Product","The one product a Product Model describes (its name, its promise, the languages it is delivered in, its known boundaries, and what it needs to be published as a Blueprint).",{"path":35,"title":36,"description":37,"group":29},"\u002Fdocs\u002Fentities","Entities","The things your product keeps or reasons about (orders, products, settings) and the people and systems that act on it, with what it knows about each and the States it moves through.",{"path":39,"title":40,"description":41,"group":29},"\u002Fdocs\u002Finterfaces","Interfaces","The web apps, mobile apps, CLIs, APIs and webhooks through which people and systems reach your product, the parts inside them, and the places where facts and abilities are met.",{"path":43,"title":44,"description":45,"group":29},"\u002Fdocs\u002Fdomains","Domains","Optional subject areas, such as ordering or billing, that follow the Product's own sections and group its Capabilities and Entities without owning them.",{"path":47,"title":48,"description":49,"group":29},"\u002Fdocs\u002Fcapabilities","Capabilities","The things your product lets someone do, where each is offered, and the Capability Scenarios that show each one working.",{"path":51,"title":52,"description":53,"group":29},"\u002Fdocs\u002Fjourneys","Journeys","Goals where your product carries a person from one Capability into the next, and the Journey Scenarios that walk each path.",{"path":55,"title":56,"description":57,"group":29},"\u002Fdocs\u002Fbusiness-rules","Business Rules","What must always hold in your product, and who may do what (constraints, derivations and permissions), each stated once with everything it applies to.",{"path":59,"title":60,"description":61,"group":29},"\u002Fdocs\u002Fvariations","Variations","Feature flags, settings, plan tiers, A\u002FB tests and API versions, when your product works in more than one supported way and something decides which way applies.",{"path":63,"title":64,"description":65,"group":29},"\u002Fdocs\u002Freferences","References","Point any resource at material kept outside the model (code, a PRD, a design, research), saying what it is and why it is attached.",{"path":67,"title":68,"description":69,"group":70},"\u002Fdocs\u002Fskills","Skills overview","Three self-contained skills cover adoption, intended product change, and automatic verification-to-resolution.","Skills",{"path":72,"title":73,"description":74,"group":70},"\u002Fdocs\u002Fskill-pdd-map","map","Create or expand a Product Model from the code you already have, without running it.",{"path":76,"title":77,"description":78,"group":70},"\u002Fdocs\u002Fskill-pdd-ideate","ideate","Explore or define intended behavior, then write only the exact Product Model change you approve.",{"path":80,"title":81,"description":82,"group":70},"\u002Fdocs\u002Fskill-pdd-verify","verify","Implement the Product Model in code, in phases, or check that the model and the code agree, and resolve every gap you approve until they do or something blocks.",{"path":84,"title":85,"description":86,"group":87},"\u002Fdocs\u002Fcli","CLI overview","Install skills, lint and view a Product Model locally, and move Blueprints between repositories with the pdd-kit CLI.","CLI",{"path":89,"title":90,"description":91,"group":87},"\u002Fdocs\u002Fcli-install","install","Install the bundled pdd-kit agent skills safely for selected AI harnesses and scopes.",{"path":93,"title":94,"description":95,"group":87},"\u002Fdocs\u002Fcli-update","update","Refresh only pdd-kit-managed skill installations in project or global scope.",{"path":97,"title":98,"description":99,"group":87},"\u002Fdocs\u002Fcli-lint","lint","Check that a Product Model is structurally sound (files, relationships, Steps, Rules and References) without claiming it matches the code.",{"path":101,"title":102,"description":103,"group":87},"\u002Fdocs\u002Fcli-view","view","Open a Product Model as a private local report, from your checkout or from a GitHub repository.",{"path":105,"title":106,"description":107,"group":87},"\u002Fdocs\u002Fcli-export","blueprint export","Compile a Product Model into a portable Product Report that can move safely between repositories.",{"path":109,"title":110,"description":111,"group":87},"\u002Fdocs\u002Fcli-open","blueprint open","Expand a local Product Report into a canonical Product Model.",{"path":113,"title":114,"description":115,"group":87},"\u002Fdocs\u002Fcli-list","blueprint list","List the published Blueprints you can pull.",{"path":117,"title":118,"description":119,"group":87},"\u002Fdocs\u002Fcli-pull","blueprint pull","Pull a published Blueprint into the current directory.",{"path":121,"title":122,"description":123,"group":87},"\u002Fdocs\u002Fcli-contribute","blueprint contribute","Open a pull request proposing your Product Model as a Blueprint.",{"id":125,"title":56,"body":126,"description":57,"extension":372,"group":29,"meta":1546,"navigation":449,"order":490,"path":55,"seo":1567,"stem":1568,"__hash__":1569},"docs\u002Fdocs\u002Fbusiness-rules.md",{"type":127,"value":128,"toc":1531},"minimark",[129,133,141,164,167,172,258,262,356,360,366,499,593,597,600,605,658,665,706,709,713,716,827,838,840,852,895,1039,1042,1046,1052,1159,1190,1331,1347,1351,1359,1363,1388,1392,1395,1476,1479,1517,1527],[130,131,56],"h1",{"id":132},"business-rules",[134,135,136,140],"p",{},[137,138,139],"strong",{},"A Business Rule is something that must always hold in your product, or who\nmay do what."," It comes in three kinds:",[142,143,144,152,158],"ul",{},[145,146,147,148,151],"li",{},"a ",[137,149,150],{},"constraint",": a refund never exceeds the charge;",[145,153,147,154,157],{},[137,155,156],{},"derivation",": Total charged equals subtotal plus tax minus discount;",[145,159,147,160,163],{},[137,161,162],{},"permission",": an order's margin is for operators only.",[134,165,166],{},"Permissions live only here. A Scenario shows someone doing a thing; the Rule\nsays whether they may.",[168,169,171],"h2",{"id":170},"in-practice","In practice",[173,174,175,191],"table",{},[176,177,178],"thead",{},[179,180,181,185,188],"tr",{},[182,183,184],"th",{},"In your product",[182,186,187],{},"The Rule",[182,189,190],{},"Kind",[192,193,194,206,216,227,238,248],"tbody",{},[179,195,196,200,203],{},[197,198,199],"td",{},"A refund can never repay more than the order cost",[197,201,202],{},"A refund never exceeds the charge",[197,204,205],{},"Constraint",[179,207,208,211,214],{},[197,209,210],{},"An order is confirmed only after its payment succeeds",[197,212,213],{},"Payment before confirmation",[197,215,205],{},[179,217,218,221,224],{},[197,219,220],{},"The total is always subtotal plus tax minus discount",[197,222,223],{},"Total charged",[197,225,226],{},"Derivation",[179,228,229,232,235],{},[197,230,231],{},"Only operators see what the store earns on an order",[197,233,234],{},"Margin is for operators",[197,236,237],{},"Permission",[179,239,240,243,246],{},[197,241,242],{},"A shopper edits delivery details only while the order is unpaid",[197,244,245],{},"Delivery details are editable while unpaid",[197,247,237],{},[179,249,250,253,256],{},[197,251,252],{},"Once refunded, an order is never cancelled, by anyone",[197,254,255],{},"A refunded order is never cancelled",[197,257,237],{},[168,259,261],{"id":260},"when-you-create-one","When you create one",[142,263,264,270,281,294,308,319,329,346],{},[145,265,266,269],{},[137,267,268],{},"It holds across behaviors, a place, or a thing."," Something true of exactly\none Capability is that Capability's own condition Step or Outcome, not a Rule.",[145,271,272,275,276,280],{},[137,273,274],{},"One Rule per assertion, however many places it applies."," ",[277,278,279],"em",{},"Payment before\nconfirmation"," governs every way an Order becomes Confirmed; it is not copied\ninto each Capability that confirms one.",[145,282,283,275,286,289,290,293],{},[137,284,285],{},"Write what must remain true, not a sequence.",[277,287,288],{},"A refund never exceeds the\ncharge",", not ",[277,291,292],{},"check the amount, then issue the refund",".",[145,295,296,299,300,303,304,307],{},[137,297,298],{},"Alternative grants share one Rule."," Two permission Rules on the same\noperation must both allow it, so ",[277,301,302],{},"the owner may"," and ",[277,305,306],{},"an admin may",", written\napart, would mean only someone who is both.",[145,309,310,313,314,318],{},[137,311,312],{},"One permission Rule per operation."," Creating, changing and removing a\nCard are three Rules, each naming its ",[315,316,317],"code",{},"effect",", even when the same people may\ndo all three.",[145,320,321,328],{},[137,322,323,324,327],{},"What goes ",[315,325,326],{},"with"," another is the other's to permit."," A Rule on removing\ncomments never selects the comments a deleted card takes with it, and a Rule\non adding members never selects the first membership a new board is created\nwith.",[145,330,331,334,335,338,339,293],{},[137,332,333],{},"A condition reads one instance, never any of many."," The actor itself; a\nper-board Role on the ",[315,336,337],{},"related"," path, the acting person's own membership;\nthe one the governed thing leads to, such as the Quiz a Question is in; or\nStore settings marked ",[340,341,343],"a",{"href":342},".\u002Fentities#the-file",[315,344,345],{},"singleton",[145,347,348,351,352,293],{},[137,349,350],{},"Ordinary copy is design; contractual wording is a Rule."," When exact words\nare required, the Rule says so and cites the authoritative\n",[340,353,355],{"href":354},".\u002Freferences","Reference",[168,357,359],{"id":358},"the-file","The file",[134,361,362,365],{},[315,363,364],{},"business-rules\u002F\u003Cid>.md",". The id and H1 state the assertion, never a verb or a\nmechanism; the lead paragraph is the Rule itself.",[367,368,374],"pre",{"className":369,"code":370,"filename":371,"language":372,"meta":373,"style":373},"language-md shiki shiki-themes pdd-kit-brand-warm pdd-kit-brand-warm material-theme-palenight","---\nappliesTo:\n  - type: entity\n    id: refund\n    facts: [Amount]\n---\n\n# A refund never exceeds the charge\n\nA refund's Amount is at most the Total charged of the order it repays.\n\n## Rationale\n\nThe order is the audit boundary for the refund.\n","business-rules\u002Fa-refund-never-exceeds-the-charge.md","md","",[315,375,376,385,395,411,422,439,444,451,462,467,474,479,488,493],{"__ignoreMap":373},[377,378,381],"span",{"class":379,"line":380},"line",1,[377,382,384],{"class":383},"sjkiA","---\n",[377,386,388,392],{"class":379,"line":387},2,[377,389,391],{"class":390},"sg1QC","appliesTo",[377,393,394],{"class":383},":\n",[377,396,398,401,404,407],{"class":379,"line":397},3,[377,399,400],{"class":383},"  -",[377,402,403],{"class":390}," type",[377,405,406],{"class":383},":",[377,408,410],{"class":409},"s9fN-"," entity\n",[377,412,414,417,419],{"class":379,"line":413},4,[377,415,416],{"class":390},"    id",[377,418,406],{"class":383},[377,420,421],{"class":409}," refund\n",[377,423,425,428,430,433,436],{"class":379,"line":424},5,[377,426,427],{"class":390},"    facts",[377,429,406],{"class":383},[377,431,432],{"class":383}," [",[377,434,435],{"class":409},"Amount",[377,437,438],{"class":383},"]\n",[377,440,442],{"class":379,"line":441},6,[377,443,384],{"class":383},[377,445,447],{"class":379,"line":446},7,[377,448,450],{"emptyLinePlaceholder":449},true,"\n",[377,452,454,458],{"class":379,"line":453},8,[377,455,457],{"class":456},"sKwZ8","#",[377,459,461],{"class":460},"sBbkF"," A refund never exceeds the charge\n",[377,463,465],{"class":379,"line":464},9,[377,466,450],{"emptyLinePlaceholder":449},[377,468,470],{"class":379,"line":469},10,[377,471,473],{"class":472},"szETn","A refund's Amount is at most the Total charged of the order it repays.\n",[377,475,477],{"class":379,"line":476},11,[377,478,450],{"emptyLinePlaceholder":449},[377,480,482,485],{"class":379,"line":481},12,[377,483,484],{"class":456},"##",[377,486,487],{"class":460}," Rationale\n",[377,489,491],{"class":379,"line":490},13,[377,492,450],{"emptyLinePlaceholder":449},[377,494,496],{"class":379,"line":495},14,[377,497,498],{"class":472},"The order is the audit boundary for the refund.\n",[173,500,501,514],{},[176,502,503],{},[179,504,505,508,511],{},[182,506,507],{},"Field or section",[182,509,510],{},"Required",[182,512,513],{},"Says",[192,515,516,528,544,559,569,581],{},[179,517,518,522,525],{},[197,519,520],{},[315,521,391],{},[197,523,524],{},"yes",[197,526,527],{},"What the Rule governs: at least one target, below",[179,529,530,535,538],{},[197,531,532],{},[315,533,534],{},"permits",[197,536,537],{},"no",[197,539,540,541],{},"Who may perform the selected operation; see ",[340,542,237],{"href":543},"#permission",[179,545,546,551,553],{},[197,547,548],{},[315,549,550],{},"references",[197,552,537],{},[197,554,555,556,558],{},"Code or documents behind it, in the ",[340,557,355],{"href":354}," shape",[179,560,561,564,566],{},[197,562,563],{},"H1 and lead",[197,565,524],{},[197,567,568],{},"The assertion, stated plainly",[179,570,571,576,578],{},[197,572,573],{},[315,574,575],{},"## Intent",[197,577,537],{},[197,579,580],{},"The outcome the Rule protects",[179,582,583,588,590],{},[197,584,585],{},[315,586,587],{},"## Rationale",[197,589,537],{},[197,591,592],{},"Why it is necessary now, not which designs were rejected",[168,594,596],{"id":595},"what-a-rule-applies-to","What a Rule applies to",[134,598,599],{},"The Rule owns its targets. Nothing else lists the Rule; every backlink is\nderived.",[601,602,604],"h3",{"id":603},"behavioral-and-context-targets","Behavioral and Context targets",[173,606,607,619],{},[176,608,609],{},[179,610,611,616],{},[182,612,613],{},[315,614,615],{},"type",[182,617,618],{},"Applies to",[192,620,621,635,648],{},[179,622,623,632],{},[197,624,625,628,629],{},[315,626,627],{},"capability",", ",[315,630,631],{},"journey",[197,633,634],{},"That behavior, wherever it is supported",[179,636,637,645],{},[197,638,639,628,642],{},[315,640,641],{},"capability-scenario",[315,643,644],{},"journey-scenario",[197,646,647],{},"One Scenario of it",[179,649,650,655],{},[197,651,652],{},[315,653,654],{},"context",[197,656,657],{},"A place, independent of any behavior",[134,659,660,661,664],{},"A behavioral target may narrow itself with ",[315,662,663],{},"contexts"," to the places it holds\nin. A place target looks like this:",[367,666,670],{"className":667,"code":668,"language":669,"meta":373,"style":373},"language-yaml shiki shiki-themes pdd-kit-brand-warm pdd-kit-brand-warm material-theme-palenight","appliesTo:\n  - type: context\n    context:\n      place: operator-cli\n","yaml",[315,671,672,678,689,696],{"__ignoreMap":373},[377,673,674,676],{"class":379,"line":380},[377,675,391],{"class":390},[377,677,394],{"class":383},[377,679,680,682,684,686],{"class":379,"line":387},[377,681,400],{"class":383},[377,683,403],{"class":390},[377,685,406],{"class":383},[377,687,688],{"class":409}," context\n",[377,690,691,694],{"class":379,"line":397},[377,692,693],{"class":390},"    context",[377,695,394],{"class":383},[377,697,698,701,703],{"class":379,"line":413},[377,699,700],{"class":390},"      place",[377,702,406],{"class":383},[377,704,705],{"class":409}," operator-cli\n",[134,707,708],{},"Do not target a Capability and one of its own Scenarios; the Capability already\ncovers it.",[601,710,712],{"id":711},"entity-targets-an-operation-on-a-thing","Entity targets: an operation on a thing",[134,714,715],{},"An Entity target names a thing and, optionally, the operation on it, such as changing\nan Order's delivery details, refunding an Order, reading its Margin:",[367,717,719],{"className":667,"code":718,"language":669,"meta":373,"style":373},"appliesTo:\n  - type: entity\n    id: order\n    effect: changes          # optional: creates | changes | removes | reads\n    from: Confirmed          # optional: the State it leaves\n    to: Refunded             # optional: the State it lands in\n    facts: [Margin]          # optional: only operations on these facts\n    contexts: [{ place: admin-web::order-console::order-detail }]   # optional\n",[315,720,721,727,737,746,760,773,786,803],{"__ignoreMap":373},[377,722,723,725],{"class":379,"line":380},[377,724,391],{"class":390},[377,726,394],{"class":383},[377,728,729,731,733,735],{"class":379,"line":387},[377,730,400],{"class":383},[377,732,403],{"class":390},[377,734,406],{"class":383},[377,736,410],{"class":409},[377,738,739,741,743],{"class":379,"line":397},[377,740,416],{"class":390},[377,742,406],{"class":383},[377,744,745],{"class":409}," order\n",[377,747,748,751,753,756],{"class":379,"line":413},[377,749,750],{"class":390},"    effect",[377,752,406],{"class":383},[377,754,755],{"class":409}," changes",[377,757,759],{"class":758},"shP-r","          # optional: creates | changes | removes | reads\n",[377,761,762,765,767,770],{"class":379,"line":424},[377,763,764],{"class":390},"    from",[377,766,406],{"class":383},[377,768,769],{"class":409}," Confirmed",[377,771,772],{"class":758},"          # optional: the State it leaves\n",[377,774,775,778,780,783],{"class":379,"line":441},[377,776,777],{"class":390},"    to",[377,779,406],{"class":383},[377,781,782],{"class":409}," Refunded",[377,784,785],{"class":758},"             # optional: the State it lands in\n",[377,787,788,790,792,794,797,800],{"class":379,"line":446},[377,789,427],{"class":390},[377,791,406],{"class":383},[377,793,432],{"class":383},[377,795,796],{"class":409},"Margin",[377,798,799],{"class":383},"]",[377,801,802],{"class":758},"          # optional: only operations on these facts\n",[377,804,805,808,810,813,816,818,821,824],{"class":379,"line":453},[377,806,807],{"class":390},"    contexts",[377,809,406],{"class":383},[377,811,812],{"class":383}," [{",[377,814,815],{"class":390}," place",[377,817,406],{"class":383},[377,819,820],{"class":409}," admin-web::order-console::order-detail",[377,822,823],{"class":383}," }]",[377,825,826],{"class":758},"   # optional\n",[134,828,829,830,833,834,837],{},"The target selects which operations; whether the thing is in some State ",[277,831,832],{},"when","\nit happens is a condition on a grant. Write the smallest selector that is true:\nrefunds only ever leave Confirmed, so ",[315,835,836],{},"{ effect: changes, to: Refunded }"," is\nthe Rule, and it still covers a refund added later from another State.",[168,839,237],{"id":162},[134,841,842,844,845,848,849,851],{},[315,843,534],{}," says who may perform the selected operation, and it needs Entity\ntargets only. A read restricted in one place (a download page) is ",[315,846,847],{},"effect: reads"," on the Entity narrowed with ",[315,850,663],{}," to that place. A restricted read\non the same Screen as ordinary reading cannot be told apart yet: say so in the\nRule's prose.",[173,853,854,864],{},[176,855,856],{},[179,857,858,862],{},[182,859,860],{},[315,861,534],{},[182,863,513],{},[192,865,866,874,887],{},[179,867,868,871],{},[197,869,870],{},"omitted",[197,872,873],{},"This Rule makes no permission claim",[179,875,876,881],{},[197,877,878],{},[315,879,880],{},"[]",[197,882,883,884,886],{},"Nobody may; a Step doing it is a ",[315,885,98],{}," error",[179,888,889,892],{},[197,890,891],{},"a list of grants",[197,893,894],{},"Anyone matching one grant may",[367,896,899],{"className":369,"code":897,"filename":898,"language":372,"meta":373,"style":373},"---\nappliesTo:\n  - type: entity\n    id: order\n    effect: changes\n    facts: [Delivery details]\npermits:\n  - related: [{ verb: owns, entity: shopper }]\n    when: [{ state: Pending }]\n---\n\n# Delivery details are editable while unpaid\n\nA shopper edits an order's delivery details only while the order is still\nunpaid.\n","business-rules\u002Fdelivery-details-are-editable-while-unpaid.md",[315,900,901,905,911,921,929,938,951,957,990,1009,1013,1017,1024,1028,1033],{"__ignoreMap":373},[377,902,903],{"class":379,"line":380},[377,904,384],{"class":383},[377,906,907,909],{"class":379,"line":387},[377,908,391],{"class":390},[377,910,394],{"class":383},[377,912,913,915,917,919],{"class":379,"line":397},[377,914,400],{"class":383},[377,916,403],{"class":390},[377,918,406],{"class":383},[377,920,410],{"class":409},[377,922,923,925,927],{"class":379,"line":413},[377,924,416],{"class":390},[377,926,406],{"class":383},[377,928,745],{"class":409},[377,930,931,933,935],{"class":379,"line":424},[377,932,750],{"class":390},[377,934,406],{"class":383},[377,936,937],{"class":409}," changes\n",[377,939,940,942,944,946,949],{"class":379,"line":441},[377,941,427],{"class":390},[377,943,406],{"class":383},[377,945,432],{"class":383},[377,947,948],{"class":409},"Delivery details",[377,950,438],{"class":383},[377,952,953,955],{"class":379,"line":446},[377,954,534],{"class":390},[377,956,394],{"class":383},[377,958,959,961,964,966,968,971,973,976,979,982,984,987],{"class":379,"line":453},[377,960,400],{"class":383},[377,962,963],{"class":390}," related",[377,965,406],{"class":383},[377,967,812],{"class":383},[377,969,970],{"class":390}," verb",[377,972,406],{"class":383},[377,974,975],{"class":409}," owns",[377,977,978],{"class":383},",",[377,980,981],{"class":390}," entity",[377,983,406],{"class":383},[377,985,986],{"class":409}," shopper",[377,988,989],{"class":383}," }]\n",[377,991,992,995,997,999,1002,1004,1007],{"class":379,"line":464},[377,993,994],{"class":390},"    when",[377,996,406],{"class":383},[377,998,812],{"class":383},[377,1000,1001],{"class":390}," state",[377,1003,406],{"class":383},[377,1005,1006],{"class":409}," Pending",[377,1008,989],{"class":383},[377,1010,1011],{"class":379,"line":469},[377,1012,384],{"class":383},[377,1014,1015],{"class":379,"line":476},[377,1016,450],{"emptyLinePlaceholder":449},[377,1018,1019,1021],{"class":379,"line":481},[377,1020,457],{"class":456},[377,1022,1023],{"class":460}," Delivery details are editable while unpaid\n",[377,1025,1026],{"class":379,"line":490},[377,1027,450],{"emptyLinePlaceholder":449},[377,1029,1030],{"class":379,"line":495},[377,1031,1032],{"class":472},"A shopper edits an order's delivery details only while the order is still\n",[377,1034,1036],{"class":379,"line":1035},15,[377,1037,1038],{"class":472},"unpaid.\n",[134,1040,1041],{},"Grants in one Rule are alternatives; the keys inside one grant must all hold.\nWhen several permission Rules select the same operation, each must allow it.\nAn operation no permission Rule selects is open.",[601,1043,1045],{"id":1044},"grant-keys","Grant keys",[134,1047,1048,1049,1051],{},"Every grant names a who; ",[315,1050,832],{}," only narrows it.",[173,1053,1054,1066],{},[176,1055,1056],{},[179,1057,1058,1061,1063],{},[182,1059,1060],{},"Key",[182,1062,513],{},[182,1064,1065],{},"Example",[192,1067,1068,1083,1098,1114,1130,1145],{},[179,1069,1070,1075,1078],{},[197,1071,1072],{},[315,1073,1074],{},"actors",[197,1076,1077],{},"These Entities may",[197,1079,1080],{},[315,1081,1082],{},"actors: [store-admin]",[179,1084,1085,1089,1092],{},[197,1086,1087],{},[315,1088,337],{},[197,1090,1091],{},"Whoever stands in this relation to the thing may",[197,1093,1094,1097],{},[315,1095,1096],{},"related: [{ verb: owns, entity: shopper }]",", the Order's own Shopper",[179,1099,1100,1105,1108],{},[197,1101,1102],{},[315,1103,1104],{},"self",[197,1106,1107],{},"The thing itself may",[197,1109,1110,1113],{},[315,1111,1112],{},"self: true",", a Shopper edits their own address",[179,1115,1116,1121,1124],{},[197,1117,1118],{},[315,1119,1120],{},"unattended",[197,1122,1123],{},"The Product's own schedule may",[197,1125,1126,1129],{},[315,1127,1128],{},"unattended: true",", cancel when the payment window closes",[179,1131,1132,1137,1140],{},[197,1133,1134],{},[315,1135,1136],{},"configuredBy",[197,1138,1139],{},"Whoever the customer configures may",[197,1141,1142],{},[315,1143,1144],{},"configuredBy: store-settings",[179,1146,1147,1151,1154],{},[197,1148,1149],{},[315,1150,832],{},[197,1152,1153],{},"Only while these conditions all hold",[197,1155,1156],{},[315,1157,1158],{},"when: [{ state: Pending }]",[134,1160,1161,1162,1164,1165,628,1168,628,1171,628,1174,628,1177,628,1180,628,1183,628,1186,1189],{},"A ",[315,1163,832],{}," condition is a State of the thing, or a fact with one operator\n(",[315,1166,1167],{},"over",[315,1169,1170],{},"under",[315,1172,1173],{},"at-least",[315,1175,1176],{},"at-most",[315,1178,1179],{},"is",[315,1181,1182],{},"is-not",[315,1184,1185],{},"present",[315,1187,1188],{},"absent","):",[367,1191,1193],{"className":667,"code":1192,"language":669,"meta":373,"style":373},"when:\n  - { state: Pending }                                                    # the thing's State\n  - { fact: Total charged, at-most: 100 }                                 # a fact of the thing\n  - { entity: store-settings, fact: Self-service cancellation, is: true } # a setting\n  - { fact: Total charged, over: { entity: store-settings, fact: Refund approval threshold } } # a threshold the store sets\n",[315,1194,1195,1201,1220,1250,1288],{"__ignoreMap":373},[377,1196,1197,1199],{"class":379,"line":380},[377,1198,832],{"class":390},[377,1200,394],{"class":383},[377,1202,1203,1205,1208,1210,1212,1214,1217],{"class":379,"line":387},[377,1204,400],{"class":383},[377,1206,1207],{"class":383}," {",[377,1209,1001],{"class":390},[377,1211,406],{"class":383},[377,1213,1006],{"class":409},[377,1215,1216],{"class":383}," }",[377,1218,1219],{"class":758},"                                                    # the thing's State\n",[377,1221,1222,1224,1226,1229,1231,1234,1236,1239,1241,1245,1247],{"class":379,"line":397},[377,1223,400],{"class":383},[377,1225,1207],{"class":383},[377,1227,1228],{"class":390}," fact",[377,1230,406],{"class":383},[377,1232,1233],{"class":409}," Total charged",[377,1235,978],{"class":383},[377,1237,1238],{"class":390}," at-most",[377,1240,406],{"class":383},[377,1242,1244],{"class":1243},"s5S7S"," 100",[377,1246,1216],{"class":383},[377,1248,1249],{"class":758},"                                 # a fact of the thing\n",[377,1251,1252,1254,1256,1258,1260,1263,1265,1267,1269,1272,1274,1277,1279,1283,1285],{"class":379,"line":413},[377,1253,400],{"class":383},[377,1255,1207],{"class":383},[377,1257,981],{"class":390},[377,1259,406],{"class":383},[377,1261,1262],{"class":409}," store-settings",[377,1264,978],{"class":383},[377,1266,1228],{"class":390},[377,1268,406],{"class":383},[377,1270,1271],{"class":409}," Self-service cancellation",[377,1273,978],{"class":383},[377,1275,1276],{"class":390}," is",[377,1278,406],{"class":383},[377,1280,1282],{"class":1281},"sIKwg"," true",[377,1284,1216],{"class":383},[377,1286,1287],{"class":758}," # a setting\n",[377,1289,1290,1292,1294,1296,1298,1300,1302,1305,1307,1309,1311,1313,1315,1317,1319,1321,1324,1326,1328],{"class":379,"line":424},[377,1291,400],{"class":383},[377,1293,1207],{"class":383},[377,1295,1228],{"class":390},[377,1297,406],{"class":383},[377,1299,1233],{"class":409},[377,1301,978],{"class":383},[377,1303,1304],{"class":390}," over",[377,1306,406],{"class":383},[377,1308,1207],{"class":383},[377,1310,981],{"class":390},[377,1312,406],{"class":383},[377,1314,1262],{"class":409},[377,1316,978],{"class":383},[377,1318,1228],{"class":390},[377,1320,406],{"class":383},[377,1322,1323],{"class":409}," Refund approval threshold",[377,1325,1216],{"class":383},[377,1327,1216],{"class":383},[377,1329,1330],{"class":758}," # a threshold the store sets\n",[134,1332,1333,275,1340,1343,1344,1346],{},[137,1334,1335,1336,293],{},"A setting that only decides who may do something is a condition, not a\n",[340,1337,1339],{"href":1338},".\u002Fvariations","Variation",[277,1341,1342],{},"Self-service cancellation"," on or off is one\ngrant's ",[315,1345,832],{},". Business Rules vary only when a setting switches between two\ncomplete policies, such as Standard or Strict refund review.",[601,1348,1350],{"id":1349},"a-products-own-roles","A product's own roles",[134,1352,1353,1354,1356,1357,293],{},"Each role the Product ships is an Entity that acts, granted through ",[315,1355,1074],{},":\none Entity per role, never one per role a customer configures. A role held per\nteam or workspace goes through a membership Entity that names it, reached by\n",[315,1358,337],{},[168,1360,1362],{"id":1361},"how-it-connects","How it connects",[142,1364,1365,1372,1378,1385],{},[145,1366,1367,1368,293],{},"A Rule reaches every Capability whose Steps perform the operation it selects,\nand governs that move in the Entity's\n",[340,1369,1371],{"href":1370},".\u002Fentities#states-and-the-lifecycle-nobody-authors","Lifecycle",[145,1373,1374,1375,1377],{},"It cites Entity facts and States by exact name, and ",[315,1376,337],{}," walks the\nEntity's declared relations.",[145,1379,1380,1381,1384],{},"Steps and Screens are checked against its grants: a Step's ",[315,1382,1383],{},"actor",", or a\nScreen's audience, must be someone a grant could admit.",[145,1386,1387],{},"Domains are never targets; a Rule's Domains are derived from what it governs.",[168,1389,1391],{"id":1390},"what-lint-checks","What lint checks",[134,1393,1394],{},"Errors:",[142,1396,1397,1402,1427,1432,1453,1466],{},[145,1398,1399,1400,293],{},"A missing H1 or lead, or an empty ",[315,1401,391],{},[145,1403,1404,1405,1408,1409,1412,1413,1416,1417,1420,1421,1412,1424,1426],{},"A target whose id, State, fact or place does not resolve; ",[315,1406,1407],{},"from"," on a\n",[315,1410,1411],{},"creates"," or ",[315,1414,1415],{},"reads"," target, ",[315,1418,1419],{},"to"," on a ",[315,1422,1423],{},"removes",[315,1425,1415],{}," one; a Capability\nor Journey targeted beside one of its own Scenarios.",[145,1428,1429,1431],{},[315,1430,534],{}," on a Rule with a non-Entity target.",[145,1433,1434,1435,1437,1438,1440,1441,1443,1444,1446,1447,1449,1450,1452],{},"A grant that names nobody; ",[315,1436,1074],{},", a ",[315,1439,337],{}," end or ",[315,1442,1104],{}," naming an\nEntity that does not act; a ",[315,1445,337],{}," hop that matches no relation, or more\nthan one, or walks a self-relation (a Comment replying to a Comment has no\ndirection); a grant whose ",[315,1448,1074],{}," leaves out the Entity its ",[315,1451,337],{}," path\nends on, so nobody could satisfy it.",[145,1454,1455,1456,1420,1459,1461,1462,1465],{},"A condition without exactly one of the eight operators, a fact or State that\ndoes not resolve, or a ",[315,1457,1458],{},"state",[315,1460,1411],{}," target; a condition ",[315,1463,1464],{},"entity","\nor threshold that could be any of many instances.",[145,1467,1468,1469,1472,1473,1475],{},"A Step performing an operation ",[315,1470,1471],{},"permits: []"," forbids; a governed operation\nwhose Step has no actor, or one no grant could admit; an unattended Scenario\nno ",[315,1474,1120],{}," grant allows; a Screen presenting governed facts to an\naudience no grant admits.",[134,1477,1478],{},"Warnings:",[142,1480,1481,1487,1490,1497,1504,1514],{},[145,1482,1483,1484,1486],{},"A Rule whose only target is one behavior with no ",[315,1485,663],{},": it belongs to\nthat Capability.",[145,1488,1489],{},"Two permission Rules with identical targets.",[145,1491,1161,1492,1412,1494,1496],{},[315,1493,1407],{},[315,1495,1458],{}," condition every selected Step already satisfies.",[145,1498,1499,1500,1503],{},"An id that opens with a verb acting on something the model declares, such as\n",[315,1501,1502],{},"cancel-unpaid-orders"," beside an Order Entity.",[145,1505,1506,1507,1510,1511,1513],{},"A grant that names ",[315,1508,1509],{},"ai-agent"," without a ",[315,1512,337],{}," path to the person whose\nagent it is.",[145,1515,1516],{},"An Actor changing or removing a thing whose other changes Rules govern, when\nno permission Rule selects that change.",[134,1518,1519,1520,1526],{},"A permission Rule that is an alternative in a Variation skips the Step and\nScreen checks; ",[340,1521,1523],{"href":1522},".\u002Fskill-pdd-verify",[315,1524,1525],{},"pdd-verify"," checks it\nagainst the code.",[1528,1529,1530],"style",{},"html pre.shiki code .sjkiA, html code.shiki .sjkiA{--shiki-light:#362B1D;--shiki-default:#362B1D;--shiki-dark:#89DDFF}html pre.shiki code .sg1QC, html code.shiki .sg1QC{--shiki-light:#00585F;--shiki-default:#00585F;--shiki-dark:#F07178}html pre.shiki code .s9fN-, html code.shiki .s9fN-{--shiki-light:#6E3500;--shiki-default:#6E3500;--shiki-dark:#C3E88D}html pre.shiki code .sKwZ8, html code.shiki .sKwZ8{--shiki-light:#362B1D;--shiki-light-font-weight:bold;--shiki-default:#362B1D;--shiki-default-font-weight:bold;--shiki-dark:#89DDFF;--shiki-dark-font-weight:inherit}html pre.shiki code .sBbkF, html code.shiki .sBbkF{--shiki-light:#00585F;--shiki-light-font-weight:bold;--shiki-default:#00585F;--shiki-default-font-weight:bold;--shiki-dark:#FFCB6B;--shiki-dark-font-weight:inherit}html pre.shiki code .szETn, html code.shiki .szETn{--shiki-light:#362B1D;--shiki-default:#362B1D;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .shP-r, html code.shiki .shP-r{--shiki-light:#4C3E2B;--shiki-light-font-style:italic;--shiki-default:#4C3E2B;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s5S7S, html code.shiki .s5S7S{--shiki-light:#00585F;--shiki-default:#00585F;--shiki-dark:#F78C6C}html pre.shiki code .sIKwg, html code.shiki .sIKwg{--shiki-light:#00585F;--shiki-default:#00585F;--shiki-dark:#FF9CAC}",{"title":373,"searchDepth":387,"depth":387,"links":1532},[1533,1534,1535,1536,1540,1544,1545],{"id":170,"depth":387,"text":171},{"id":260,"depth":387,"text":261},{"id":358,"depth":387,"text":359},{"id":595,"depth":387,"text":596,"children":1537},[1538,1539],{"id":603,"depth":397,"text":604},{"id":711,"depth":397,"text":712},{"id":162,"depth":387,"text":237,"children":1541},[1542,1543],{"id":1044,"depth":397,"text":1045},{"id":1349,"depth":397,"text":1350},{"id":1361,"depth":387,"text":1362},{"id":1390,"depth":387,"text":1391},{"section":1547,"terms":1548},"open-source",[1549,1554,1558,1563],{"term":1550,"aliases":1551,"definition":1553},"Business Rule",[1552],"Rule","Something that must always hold in the Product, or who may do what. It is the only place the model says who may act.",{"term":618,"aliases":1555,"anchor":603,"definition":1557},[1556],"Binding","What a Rule governs: a Capability, a Journey, one of their Scenarios, a place, or an operation on a thing.",{"term":1559,"aliases":1560,"anchor":711,"definition":1562},"Operation",[1561],"What it changes","What may be done to a thing: creates, changes, removes, or reads. A Step calls it an effect; a Business Rule selects the same word as an operation.",{"term":1564,"aliases":1565,"anchor":162,"definition":1566},"Who may",[237],"Who may perform an operation on a thing, listed as grants in a Business Rule. An empty list means nobody may.",{"title":56,"description":57},"docs\u002Fbusiness-rules","4El2HP0lkePxgd9_tEed9iQe-u0FV9TY8iR5P3vExZQ",1791840531138]