{
  "id": "apex-company-os",
  "name": "Apex Instruments Company OS packages",
  "version": "2026.09",
  "note": "One registry file. Everything installable is in it, including the two that are not ready, because a registry that hides its broken entries is how somebody installs one by accident.",
  "rule": "Every package ships at least one skill, one template, and one check. Agents and guides are optional: not everything needs a standing job, and a package small enough to install from its steps alone does not need prose.",
  "honest": "Packaging is what makes a system survive its author. The test of a package is whether somebody can install it without asking you anything.",
  "audiences": [
    {
      "id": "everyone",
      "label": "Everyone",
      "who": "Anyone who works in the workspace, including the assistant."
    },
    {
      "id": "operations",
      "label": "Operations",
      "who": "Whoever owns the facts, the folders, and the numbers."
    },
    {
      "id": "marketing",
      "label": "Marketing",
      "who": "Whoever owns the brand, the copy, and the campaigns."
    },
    {
      "id": "sales",
      "label": "Sales",
      "who": "Whoever writes proposals and talks to partners."
    },
    {
      "id": "success",
      "label": "Customer success",
      "who": "Whoever handles renewals, onboarding, and support writing."
    },
    {
      "id": "leadership",
      "label": "Leadership",
      "who": "Whoever signs things off and sets the quarter."
    },
    {
      "id": "admin",
      "label": "Whoever installs it",
      "who": "One person with rights to create folders and set permissions. Often not the same person who uses it."
    }
  ],
  "contentKinds": [
    {
      "id": "skills",
      "label": "Skills",
      "note": "A written procedure the assistant follows. Names its template, its slots, and what it must escalate."
    },
    {
      "id": "agents",
      "label": "Agents",
      "note": "A standing job with a trigger, a scope, and a thing it is not allowed to decide."
    },
    {
      "id": "templates",
      "label": "Templates",
      "note": "An approved frame with the slots marked. Work starts from one rather than from a blank page."
    },
    {
      "id": "guides",
      "label": "Guides",
      "note": "Written for a person, not for the assistant. The test is whether they can follow it alone."
    },
    {
      "id": "checks",
      "label": "Checks",
      "note": "Something that runs and reports. A check that cannot fail is not a check."
    }
  ],
  "environmentPrereqs": [
    {
      "id": "provider-chosen",
      "label": "A workspace provider is chosen",
      "short": "provider chosen",
      "how": "Pick one of a shared drive, a document library, an object store, or a git repository, and make sure every person has an account on it.",
      "note": "Not which one. Just that it is decided and everyone can get in."
    },
    {
      "id": "admin-rights",
      "label": "Someone can create top level folders and set permissions",
      "short": "admin rights",
      "how": "Get one named person the rights to create a folder at the root and set a group on it.",
      "note": "This is the step that quietly blocks installs for a fortnight. Do it before anything else."
    },
    {
      "id": "people-list",
      "label": "The list of people and roles exists",
      "short": "people list",
      "how": "Write one file: name, role, and what each person owns. Five rows is enough to start.",
      "note": "Half the packages read this to decide who reviews what."
    },
    {
      "id": "assistant-identity",
      "label": "The assistant has its own login",
      "short": "assistant identity",
      "how": "Create an account for the assistant. Do not let it use a person’s credentials.",
      "note": "If the assistant signs in as a person, the activity record stops being able to tell you who did what."
    },
    {
      "id": "runner",
      "label": "Somewhere to run the checks",
      "short": "a check runner",
      "how": "A laptop with Node installed, or a scheduled job on whatever build service you already have.",
      "note": "Checks that only run on one person’s machine stop running the week that person is away."
    },
    {
      "id": "price-source",
      "label": "One authoritative price file exists",
      "short": "a price source",
      "how": "Find the spreadsheet everyone actually quotes from and agree it is the one.",
      "note": "It does not have to be tidy yet. It has to be singular."
    },
    {
      "id": "slide-masters",
      "label": "Slide masters exist as a file",
      "short": "slide masters",
      "how": "Export the master layouts from whatever tool the decks are built in.",
      "note": "If there are three competing master files, that is the thing to fix before installing anything."
    },
    {
      "id": "mail-domain",
      "label": "Control of the sending domain",
      "short": "the mail domain",
      "how": "Confirm you can add records for the domain the email goes out from.",
      "note": "Templates install fine without it. Sending does not."
    }
  ],
  "assumedMissing": [
    "assistant-identity",
    "runner",
    "slide-masters",
    "mail-domain"
  ],
  "knownCycle": {
    "packages": [
      "crm-bridge",
      "partner-portal"
    ],
    "explain": "CRM Bridge names Partner Portal as a prerequisite and Partner Portal names CRM Bridge. Neither can go first, so no install order exists. This is left in the registry on purpose: it is the case the plan builder has to refuse rather than guess at."
  },
  "packages": [
    {
      "id": "workspace-foundation",
      "name": "Workspace Foundation",
      "version": "1.4.0",
      "status": "stable",
      "audience": [
        "everyone",
        "operations",
        "admin"
      ],
      "forWhom": "The person setting the company up. Everyone else feels it without installing it.",
      "summary": "The folder scheme, the permission groups, the five stage pipeline per person, and the readme that tells a new joiner what goes where. Nothing else installs cleanly until this one has.",
      "contains": {
        "skills": [
          {
            "name": "Where does this go",
            "note": "Given a piece of work, names the one folder it belongs in and refuses to guess between two."
          },
          {
            "name": "Open a work item",
            "note": "Creates an intake entry with an owner, a kind, and a due date. Refuses an item with no owner."
          },
          {
            "name": "Move a stage",
            "note": "Moves a piece between the five stages and writes the move to the activity record."
          }
        ],
        "agents": [
          {
            "name": "Stage keeper",
            "note": "Nightly. Flags anything sitting in one stage longer than its kind allows. Reports, never moves."
          },
          {
            "name": "Orphan finder",
            "note": "Weekly. Lists files that are not in any stage and any folder that is not in the scheme."
          }
        ],
        "templates": [
          {
            "name": "Folder readme",
            "note": "One per top level folder: what belongs, what does not, who writes it."
          },
          {
            "name": "Work item",
            "note": "The intake frame: request, owner, kind, due date, and the reason it matters."
          }
        ],
        "guides": [
          {
            "name": "Installing the workspace",
            "note": "The full guide, in data/guide.md. Written for somebody who has not done this before."
          },
          {
            "name": "The first week",
            "note": "What to do on days one through five so the shape survives contact with real work."
          },
          {
            "name": "Adding a person",
            "note": "The six things to do when somebody joins, in order."
          }
        ],
        "checks": [
          {
            "name": "Scheme check",
            "note": "Every folder in the scheme exists and nothing exists that is not in the scheme."
          },
          {
            "name": "Permission check",
            "note": "Reads the effective permission on every stage folder and compares it to the published rule."
          },
          {
            "name": "Readme check",
            "note": "Every top level folder has a readme and no readme is empty."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "admin-rights",
        "people-list"
      ],
      "requires": [],
      "minutes": 95,
      "steps": [
        {
          "do": "Decide where it lives and write that down.",
          "check": "One sentence in a note somewhere: the workspace is on X."
        },
        {
          "do": "Create the root folder and the five shared folders inside it.",
          "check": "facts, approved, templates, knowledge, plans all exist."
        },
        {
          "do": "Create the six permission groups and put people in them.",
          "check": "Every person is in at least one group and nobody is in all of them."
        },
        {
          "do": "Set read on the whole root to everyone.",
          "check": "Sign in as the least privileged person and open every shared folder."
        },
        {
          "do": "Set write on each shared folder to the group named in the scheme.",
          "check": "The permission check passes."
        },
        {
          "do": "Create the work folder and one zone per person.",
          "check": "One folder per name in the people list."
        },
        {
          "do": "Create the five stage folders inside every zone.",
          "check": "Five folders per zone, spelled the same way in every one."
        },
        {
          "do": "Lock the approved stage so only the route can write to it.",
          "check": "Try to drop a file in as yourself. It should be refused."
        },
        {
          "do": "Copy the folder readme template into each top level folder and fill it in.",
          "check": "The readme check passes."
        },
        {
          "do": "Give the assistant its own account and put it in the groups it needs.",
          "check": "The assistant can read facts and write to any intake folder, and nothing else."
        },
        {
          "do": "Install the three skills and the two agents.",
          "check": "Ask the assistant where a spec sheet goes. It should name one folder."
        },
        {
          "do": "Run all three checks and fix what they report.",
          "check": "Three green results, or a written reason for each one you are leaving."
        }
      ],
      "verifies": [
        "A person who has never seen the workspace can find where a proposal goes without asking.",
        "Nobody can write into approved by hand.",
        "The assistant reads the same paths a person does."
      ],
      "note": "The largest package here and the one everything else depends on. Budget an afternoon, not a lunch break.",
      "counts": {
        "skills": 3,
        "agents": 2,
        "templates": 2,
        "guides": 3,
        "checks": 3
      },
      "itemCount": 13,
      "stepCount": 12
    },
    {
      "id": "facts-register",
      "name": "Facts Register",
      "version": "1.2.0",
      "status": "stable",
      "audience": [
        "operations",
        "everyone"
      ],
      "forWhom": "Operations installs it. Everybody quotes it.",
      "summary": "One folder holding the numbers, names, and dates every other package reads. Prices, products, service plans, people, contacts, and calendars, each with an owner and an effective date.",
      "contains": {
        "skills": [
          {
            "name": "Quote a fact",
            "note": "Returns a value with its source file and effective date. Will not answer from memory."
          },
          {
            "name": "Record a decision",
            "note": "Writes a dated record when a person overrules a source, with the reason."
          }
        ],
        "agents": [
          {
            "name": "Effective date watcher",
            "note": "Daily. Names any fact whose effective date has passed and who owns it."
          }
        ],
        "templates": [
          {
            "name": "Fact file",
            "note": "Subject, owner, effective date, value, and where the value came from."
          },
          {
            "name": "Decision record",
            "note": "What, who, when, why, scope, and when to look at it again."
          }
        ],
        "guides": [
          {
            "name": "What counts as a fact",
            "note": "The test: if two people would write it differently, it is not a fact yet."
          },
          {
            "name": "Retiring a fact",
            "note": "How to replace a number without breaking the documents that quote it."
          }
        ],
        "checks": [
          {
            "name": "Duplicate number check",
            "note": "Finds the same figure recorded in two files and names both."
          },
          {
            "name": "Stale fact check",
            "note": "Lists facts past their effective date with no successor."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "people-list",
        "price-source"
      ],
      "requires": [
        "workspace-foundation"
      ],
      "minutes": 55,
      "steps": [
        {
          "do": "Create the six subject folders under facts.",
          "check": "prices, products, service-plans, people, contacts, calendars."
        },
        {
          "do": "Move the one price file you agreed on into facts/prices and delete every other copy.",
          "check": "A search for the product name returns one price file."
        },
        {
          "do": "Fill in the fact file template for each subject.",
          "check": "Every file has an owner and an effective date at the top."
        },
        {
          "do": "Install the two skills and the watcher agent.",
          "check": "Ask for a price. The answer should cite the file and the date."
        },
        {
          "do": "Run the duplicate number check and resolve everything it finds.",
          "check": "Zero duplicates, or a written reason for each one kept."
        }
      ],
      "verifies": [
        "Asking for a price gives you the file it came from.",
        "There is exactly one place a given number lives."
      ],
      "note": "The cheapest package to install and the one that makes every other one worth having.",
      "counts": {
        "skills": 2,
        "agents": 1,
        "templates": 2,
        "guides": 2,
        "checks": 2
      },
      "itemCount": 9,
      "stepCount": 5
    },
    {
      "id": "brand-kit",
      "name": "Brand Kit",
      "version": "2.1.0",
      "status": "stable",
      "audience": [
        "marketing",
        "everyone"
      ],
      "forWhom": "Marketing owns it. Everything that produces an output reads it.",
      "summary": "The token set, the type rules, the logo files, and the checker that tells you which rule an output broke. One published set of values, in one place, that generated work reads rather than guesses.",
      "contains": {
        "skills": [
          {
            "name": "Apply the brand",
            "note": "Fills an approved template with approved tokens. Cannot introduce a colour that is not on the list."
          },
          {
            "name": "Explain a finding",
            "note": "Given a brand check result, says which rule fired, why it exists, and what the fix is."
          }
        ],
        "agents": [
          {
            "name": "Brand guardian",
            "note": "On every piece entering review. Reports near miss colours, wrong fonts, and spacing that is not on the scale."
          }
        ],
        "templates": [
          {
            "name": "Token sheet",
            "note": "Every colour, type size, and spacing step with its name and its allowed use."
          },
          {
            "name": "Logo kit",
            "note": "Lockups, clear space, minimum sizes, approved backgrounds, and three things never to do."
          }
        ],
        "guides": [
          {
            "name": "Reading a brand finding",
            "note": "What each severity means and who decides when the checker and a person disagree."
          },
          {
            "name": "Adding a token",
            "note": "Why this is a decision and not a formatting choice, and who makes it."
          }
        ],
        "checks": [
          {
            "name": "Colour check",
            "note": "Flags any value within 28 units of an approved colour but not equal to it."
          },
          {
            "name": "Font check",
            "note": "Flags substituted families against a table of the usual replacements."
          },
          {
            "name": "One accent check",
            "note": "Flags a page using the accent colour more than once."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "admin-rights"
      ],
      "requires": [
        "workspace-foundation"
      ],
      "minutes": 45,
      "steps": [
        {
          "do": "Put the token sheet in approved/brand and fill in every value.",
          "check": "No token is left as a placeholder."
        },
        {
          "do": "Put the logo files beside it with the clear space and minimum size rules written down.",
          "check": "Somebody who has never seen the logo can place it correctly from the sheet alone."
        },
        {
          "do": "Install the two skills.",
          "check": "Ask for a heading. It should come back in the display face at a size on the scale."
        },
        {
          "do": "Turn the brand guardian on for pieces entering review.",
          "check": "Push a piece with an off brand colour into review and read the finding."
        },
        {
          "do": "Run the three checks on the last five things you published.",
          "check": "Every finding is either fixed or written down as an accepted exception."
        }
      ],
      "verifies": [
        "A generated piece uses no colour that is not on the token sheet.",
        "A finding names the rule, not just the pixel."
      ],
      "note": "Install this before any package that produces an output, or the outputs will be wrong and you will fix them by hand.",
      "counts": {
        "skills": 2,
        "agents": 1,
        "templates": 2,
        "guides": 2,
        "checks": 3
      },
      "itemCount": 10,
      "stepCount": 5
    },
    {
      "id": "approval-route",
      "name": "Approval Route",
      "version": "1.1.0",
      "status": "stable",
      "audience": [
        "operations",
        "leadership",
        "admin"
      ],
      "forWhom": "Operations installs it, leadership lives in it.",
      "summary": "The review route as data: what triggers a review, who reviews what, how long they have, what happens on a rejection, and what happens when nobody answers. Plus the record every approval leaves behind.",
      "contains": {
        "skills": [
          {
            "name": "Send to review",
            "note": "Moves a piece, names the reviewers from the route, and starts the clock."
          },
          {
            "name": "Record a decision",
            "note": "Writes the eight field approval record and moves the file. The only thing that writes into approved."
          }
        ],
        "agents": [
          {
            "name": "Review clock",
            "note": "Hourly. Sends the one day reminder and handles the timeout. Never approves anything."
          },
          {
            "name": "Route reporter",
            "note": "Weekly. How many pieces went through, how many were returned, and the median time to a decision."
          }
        ],
        "templates": [
          {
            "name": "Route file",
            "note": "Triggers, reviewer rules by kind, the clock, and the two failure paths."
          },
          {
            "name": "Approval record",
            "note": "Piece, version, reviewer, decision, reason, time, which rule ran, and where it went."
          }
        ],
        "guides": [
          {
            "name": "Setting your reviewer rules",
            "note": "How to work out who should read what without giving everything to one person."
          },
          {
            "name": "What to do when the clock runs out",
            "note": "Escalation, cover, and why silence never counts as a yes."
          }
        ],
        "checks": [
          {
            "name": "Approved folder check",
            "note": "Every file in approved has a record beside it. Anything without one is named."
          },
          {
            "name": "Reviewer coverage check",
            "note": "Every kind of piece has at least one named reviewer who is not the usual author."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "people-list",
        "assistant-identity"
      ],
      "requires": [
        "workspace-foundation"
      ],
      "minutes": 40,
      "steps": [
        {
          "do": "Fill in the route file: one row per kind of piece.",
          "check": "Every kind has a reviewer count, even if the count is zero."
        },
        {
          "do": "Set the clock. Two working days is a sensible start.",
          "check": "Written in working days, not calendar days."
        },
        {
          "do": "Install the two skills and give only the route write access to approved.",
          "check": "Try to write into approved as a person. It should be refused."
        },
        {
          "do": "Turn on the review clock agent.",
          "check": "Push a piece to review and confirm the reminder arrives after a day."
        },
        {
          "do": "Run the approved folder check.",
          "check": "Every file already sitting in approved either gets a record or gets moved out."
        }
      ],
      "verifies": [
        "Nothing reaches approved without a named person and a timestamp.",
        "A review that nobody answers comes back rather than going through."
      ],
      "note": "The reviewer coverage check usually fails the first time. That failure is the useful part.",
      "counts": {
        "skills": 2,
        "agents": 2,
        "templates": 2,
        "guides": 2,
        "checks": 2
      },
      "itemCount": 10,
      "stepCount": 5
    },
    {
      "id": "house-style",
      "name": "House Style",
      "version": "1.6.0",
      "status": "stable",
      "audience": [
        "everyone",
        "marketing"
      ],
      "forWhom": "Anybody who writes. Marketing owns the register.",
      "summary": "The written style: sentence shapes, the phrase register of banned and approved wording, and the scanner that marks a banned phrase in place and offers the approved alternative.",
      "contains": {
        "skills": [
          {
            "name": "Write in house style",
            "note": "Applies the style rules to a draft and lists what it changed and why."
          },
          {
            "name": "Explain a phrase ruling",
            "note": "Says why a phrase is on the register and what to use instead."
          }
        ],
        "agents": [
          {
            "name": "Phrase scanner",
            "note": "On every piece entering review. Marks banned phrases in place with the approved alternative."
          }
        ],
        "templates": [
          {
            "name": "Phrase register",
            "note": "Banned phrase, its variants, the reason, and one or two approved alternatives."
          },
          {
            "name": "Worked example",
            "note": "The same paragraph written badly and written well, with the difference named."
          }
        ],
        "guides": [
          {
            "name": "Adding to the register",
            "note": "A phrase gets banned with a reason and an alternative, never with just a dislike."
          }
        ],
        "checks": [
          {
            "name": "Register scan",
            "note": "Runs the register over a body of text and reports every hit with its position."
          },
          {
            "name": "Readability check",
            "note": "Flags sentences over a length the register sets and paragraphs with no verb in the first clause."
          }
        ]
      },
      "prereqs": [
        "provider-chosen"
      ],
      "requires": [
        "workspace-foundation",
        "brand-kit"
      ],
      "minutes": 30,
      "steps": [
        {
          "do": "Write ten style rules. Ten is enough to start and more than most companies have.",
          "check": "Each rule has an example of it being broken."
        },
        {
          "do": "Fill the phrase register with the twenty phrases that already annoy you.",
          "check": "Every banned phrase has a reason and an alternative."
        },
        {
          "do": "Install the two skills and the scanner.",
          "check": "Paste a paragraph containing a banned phrase and read what comes back."
        },
        {
          "do": "Run the register scan over last quarter’s published pieces.",
          "check": "The list is your real starting register, not the one you imagined."
        }
      ],
      "verifies": [
        "A banned phrase is caught with the approved alternative attached.",
        "Every rule has an example, so nobody argues about what it means."
      ],
      "note": "The fastest package to install and the one people notice first.",
      "counts": {
        "skills": 2,
        "agents": 1,
        "templates": 2,
        "guides": 1,
        "checks": 2
      },
      "itemCount": 8,
      "stepCount": 4
    },
    {
      "id": "document-desk",
      "name": "Document Desk",
      "version": "3.0.1",
      "status": "stable",
      "audience": [
        "marketing",
        "sales",
        "success"
      ],
      "forWhom": "Anybody who has to produce a one pager, a spec sheet, a letter, or a proposal.",
      "summary": "The document templates with their slots defined, the skills that fill them from the facts register, and the render step that produces the web page and the PDF from one source.",
      "contains": {
        "skills": [
          {
            "name": "Build a one pager",
            "note": "Picks the approved frame, fills the slots from facts, escalates anything that does not fit."
          },
          {
            "name": "Build a proposal",
            "note": "Same, with the pricing section read from the price file rather than typed."
          },
          {
            "name": "Write a letter",
            "note": "Customer letters on the approved frame with the service plan terms pulled in."
          },
          {
            "name": "Render once",
            "note": "One source produces the page and the PDF, so the two cannot disagree."
          }
        ],
        "agents": [
          {
            "name": "Slot auditor",
            "note": "On save. Reports any slot left with placeholder text in it."
          }
        ],
        "templates": [
          {
            "name": "One pager",
            "note": "Six slots, a fixed heading order, and a maximum length per slot."
          },
          {
            "name": "Spec sheet",
            "note": "A specification table that reads its rows from the products folder."
          },
          {
            "name": "Letter",
            "note": "Salutation, three body slots, and a signature block from the people list."
          },
          {
            "name": "Proposal",
            "note": "Scope, pricing, terms, and a summary, with pricing locked to the price file."
          }
        ],
        "guides": [
          {
            "name": "Filling a slot properly",
            "note": "What a slot will accept and what it will refuse, with examples of both."
          },
          {
            "name": "When to escalate instead",
            "note": "The rule: a genuinely new layout is a request to a person, not a decision for the assistant."
          }
        ],
        "checks": [
          {
            "name": "Placeholder check",
            "note": "No document leaves with template text still in it."
          },
          {
            "name": "Price agreement check",
            "note": "Every figure in a document is compared against the price file and differences are listed."
          },
          {
            "name": "Heading order check",
            "note": "Headings appear in the order the template defines."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "runner"
      ],
      "requires": [
        "brand-kit",
        "facts-register"
      ],
      "minutes": 50,
      "steps": [
        {
          "do": "Put the four templates in templates/documents and mark every slot.",
          "check": "Each slot has a name, a type, and a maximum length."
        },
        {
          "do": "Point each template at the facts it reads.",
          "check": "The proposal pricing section names the price file, not a number."
        },
        {
          "do": "Install the four skills.",
          "check": "Ask for a one pager. It should come back on the frame with real figures in it."
        },
        {
          "do": "Turn the slot auditor on.",
          "check": "Leave a placeholder in on purpose and confirm it is reported."
        },
        {
          "do": "Set the render step up on the runner.",
          "check": "One command produces both the page and the PDF."
        },
        {
          "do": "Run all three checks against the output.",
          "check": "Zero placeholders, zero price differences, headings in order."
        }
      ],
      "verifies": [
        "A generated document quotes a price you can trace to a file.",
        "The PDF and the page say the same thing because they came from the same source."
      ],
      "note": "Version 3 changed the slot definition format. If you are on version 2, read the upgrade note in the guide before installing.",
      "counts": {
        "skills": 4,
        "agents": 1,
        "templates": 4,
        "guides": 2,
        "checks": 3
      },
      "itemCount": 14,
      "stepCount": 6
    },
    {
      "id": "deck-desk",
      "name": "Deck Desk",
      "version": "2.2.0",
      "status": "stable",
      "audience": [
        "marketing",
        "sales"
      ],
      "forWhom": "Anybody who has to stand up in front of a partner with slides.",
      "summary": "The slide masters, the approved slide library, and the skill that assembles a deck from existing slides rather than designing new ones.",
      "contains": {
        "skills": [
          {
            "name": "Assemble a deck",
            "note": "Builds from the approved library. Will not invent a layout."
          },
          {
            "name": "Cut a deck down",
            "note": "Given a length, says which slides to drop and why, and leaves the decision to a person."
          }
        ],
        "agents": [
          {
            "name": "Library drift watcher",
            "note": "Weekly. Names slides in circulation that are not in the approved library."
          }
        ],
        "templates": [
          {
            "name": "Slide masters",
            "note": "One layout per kind of slide, with the rule for when each is used."
          },
          {
            "name": "Slide library",
            "note": "The approved slides, each tagged with what it is for."
          }
        ],
        "guides": [
          {
            "name": "Adding a slide to the library",
            "note": "What has to be true before a slide becomes reusable."
          },
          {
            "name": "Deck length",
            "note": "Why twelve is usually right and how to get there."
          }
        ],
        "checks": [
          {
            "name": "Master conformance check",
            "note": "Flags a slide that is not on one of the masters."
          },
          {
            "name": "Orphan slide check",
            "note": "Lists slides in decks that are not in the library."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "slide-masters"
      ],
      "requires": [
        "brand-kit",
        "facts-register"
      ],
      "minutes": 45,
      "steps": [
        {
          "do": "Put the masters in templates/decks and write down which layout is used when.",
          "check": "Every layout has a stated purpose."
        },
        {
          "do": "Move the slides worth reusing into the library and tag each one.",
          "check": "Every slide in the library says what it is for."
        },
        {
          "do": "Install the two skills.",
          "check": "Ask for a partner deck. Every slide should come from the library."
        },
        {
          "do": "Turn the drift watcher on.",
          "check": "It names at least one orphan slide the first time it runs. They always do."
        },
        {
          "do": "Run both checks on the deck you presented most recently.",
          "check": "Fix or accept every finding in writing."
        }
      ],
      "verifies": [
        "An assembled deck contains no slide that has never been reviewed.",
        "The library is smaller than the number of slides in circulation, which is the point."
      ],
      "note": "Needs the slide masters as a file before you start. Three competing master files is a problem to solve first, not during.",
      "counts": {
        "skills": 2,
        "agents": 1,
        "templates": 2,
        "guides": 2,
        "checks": 2
      },
      "itemCount": 9,
      "stepCount": 5
    },
    {
      "id": "sheet-desk",
      "name": "Sheet Desk",
      "version": "1.5.0",
      "status": "stable",
      "audience": [
        "operations",
        "sales"
      ],
      "forWhom": "Anybody who gets sent a messy export and has to turn it into something readable.",
      "summary": "Workbook templates with the column set and formats fixed, the skill that turns an export into one of them, and the validation that runs before anybody reads a number off it.",
      "contains": {
        "skills": [
          {
            "name": "Rebuild a workbook",
            "note": "Maps an export onto an approved column set, runs the validation, and reports every column it could not place."
          },
          {
            "name": "Summarise a sheet",
            "note": "Produces the summary tab from the data tab. Never edits the data tab."
          }
        ],
        "agents": [],
        "templates": [
          {
            "name": "Account review workbook",
            "note": "Fixed columns, fixed formats, one summary tab."
          },
          {
            "name": "Price workbook",
            "note": "The column set other systems read. Changing it is an integration change."
          }
        ],
        "guides": [
          {
            "name": "Mapping a messy export",
            "note": "What to do with a column that does not fit, which is usually not to invent one."
          }
        ],
        "checks": [
          {
            "name": "Column set check",
            "note": "Every expected column is present and nothing extra has crept in."
          },
          {
            "name": "Type check",
            "note": "Dates are dates, numbers are numbers, and blank is not zero."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "runner"
      ],
      "requires": [
        "facts-register"
      ],
      "minutes": 35,
      "steps": [
        {
          "do": "Put the two workbook templates in templates/sheets.",
          "check": "Both have their column set written down separately from the file."
        },
        {
          "do": "Install the two skills.",
          "check": "Feed it last month’s export and read the list of columns it could not place."
        },
        {
          "do": "Run the rebuild on a sheet with a text value in a number column.",
          "check": "The validation report names the cell rather than silently coercing it."
        },
        {
          "do": "Run both checks on the workbook you use most.",
          "check": "The column set matches and no blank is being read as a zero."
        }
      ],
      "verifies": [
        "An unplaceable column is reported rather than guessed at.",
        "Nobody reads a number off a sheet that has not been validated."
      ],
      "note": "The only package with no standing agent. A sheet needs checking when somebody hands you one, not every night, so the validation runs inside the rebuild skill instead.",
      "counts": {
        "skills": 2,
        "agents": 0,
        "templates": 2,
        "guides": 1,
        "checks": 2
      },
      "itemCount": 7,
      "stepCount": 4
    },
    {
      "id": "price-desk",
      "name": "Price Desk",
      "version": "2.0.0",
      "status": "stable",
      "audience": [
        "operations",
        "sales"
      ],
      "forWhom": "Whoever owns the price list, and whoever quotes from it.",
      "summary": "The price rebuild pipeline and the proofer. Turns whatever the price list currently is into verifiable rows, then checks every document that quotes a price against them, without ever editing a price itself.",
      "contains": {
        "skills": [
          {
            "name": "Rebuild the price list",
            "note": "Produces one row per line item with a stable id, and lists every row that moved."
          },
          {
            "name": "Proof a price table",
            "note": "Compares a table in a document against the source and reports differences. Changes nothing."
          }
        ],
        "agents": [
          {
            "name": "Price proofer",
            "note": "On every piece entering review that contains a figure. Reports differences to the owner."
          },
          {
            "name": "Effective date agent",
            "note": "On the effective date, names every document quoting a price that just changed."
          }
        ],
        "templates": [
          {
            "name": "Price row",
            "note": "sku, item, category, list price, partner price, unit, effective date."
          },
          {
            "name": "Change summary",
            "note": "What moved, by how much, and who signed it."
          }
        ],
        "guides": [
          {
            "name": "Running a price change",
            "note": "The order of operations, including who has to sign before anything is published."
          },
          {
            "name": "Why the proofer never edits",
            "note": "A price is a decision. A checker that fixes prices is a checker that makes decisions."
          }
        ],
        "checks": [
          {
            "name": "Row integrity check",
            "note": "Every row has a sku, a price, and a date, and no sku appears twice."
          },
          {
            "name": "Partner margin check",
            "note": "Every partner price sits at the agreed distance from list, and names the ones that do not."
          },
          {
            "name": "Document agreement check",
            "note": "Every published document quoting a price agrees with the current list."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "price-source",
        "runner"
      ],
      "requires": [
        "facts-register",
        "sheet-desk",
        "approval-route"
      ],
      "minutes": 60,
      "steps": [
        {
          "do": "Run the rebuild against the price source and read the row count.",
          "check": "The count matches what you expected, or you find out why it does not."
        },
        {
          "do": "Fix the rows the integrity check names.",
          "check": "No duplicate skus, no missing dates."
        },
        {
          "do": "Set the partner margin rule and run the margin check.",
          "check": "Every exception is written down with who agreed it."
        },
        {
          "do": "Publish the rebuilt list into facts/prices with its effective date.",
          "check": "The old list is archived, not deleted."
        },
        {
          "do": "Install the two skills and turn both agents on.",
          "check": "Push a document with a wrong price into review and read the finding."
        },
        {
          "do": "Run the document agreement check across everything already published.",
          "check": "Every difference is either corrected or explained."
        }
      ],
      "verifies": [
        "A wrong price in a document is found before a customer finds it.",
        "The proofer has never changed a number, which is what makes its reports trustworthy."
      ],
      "note": "Needs the approval route installed first, because a price change is the case the route exists for.",
      "counts": {
        "skills": 2,
        "agents": 2,
        "templates": 2,
        "guides": 2,
        "checks": 3
      },
      "itemCount": 11,
      "stepCount": 6
    },
    {
      "id": "campaign-desk",
      "name": "Campaign Desk",
      "version": "1.3.0",
      "status": "stable",
      "audience": [
        "marketing"
      ],
      "forWhom": "Whoever runs a launch or a campaign end to end.",
      "summary": "One brief produces the whole kit: the piece list with owners and dates, the documents, the deck, and the email sequence, all on the same facts and the same frames.",
      "contains": {
        "skills": [
          {
            "name": "Read a brief",
            "note": "Turns a brief into a piece list with an owner and a date against every item."
          },
          {
            "name": "Build a kit",
            "note": "Produces every piece on the list from the desks already installed."
          },
          {
            "name": "Report on a launch",
            "note": "What shipped, what slipped, and what is still in review."
          }
        ],
        "agents": [
          {
            "name": "Launch tracker",
            "note": "Daily during a launch. Names every item with no movement and who owns it."
          }
        ],
        "templates": [
          {
            "name": "Campaign brief",
            "note": "Audience, message, channels, what each piece is for, and how it is measured."
          },
          {
            "name": "Piece list",
            "note": "One row per deliverable: kind, owner, due date, stage."
          },
          {
            "name": "Email sequence",
            "note": "Frames for a sequence, with the subject line patterns that are cleared."
          }
        ],
        "guides": [
          {
            "name": "Writing a brief the system can read",
            "note": "The five things a brief has to say before anything can be built from it."
          },
          {
            "name": "Running a launch week",
            "note": "What the tracker is for and what it is not for."
          }
        ],
        "checks": [
          {
            "name": "Coverage check",
            "note": "Every piece named in the brief exists on the list and has an owner."
          },
          {
            "name": "Date sanity check",
            "note": "Nothing is due after the launch date and nothing has a due date in the past."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "mail-domain"
      ],
      "requires": [
        "document-desk",
        "deck-desk",
        "house-style"
      ],
      "minutes": 55,
      "steps": [
        {
          "do": "Put the brief template in plans/campaigns and fill it in for a real campaign.",
          "check": "All five required sections are answered."
        },
        {
          "do": "Install the three skills.",
          "check": "Feed it the brief. It should return a piece list with owners."
        },
        {
          "do": "Build one piece of the kit and read it properly.",
          "check": "It came out on the frame with the right facts in it."
        },
        {
          "do": "Turn the launch tracker on and set the launch date.",
          "check": "It names a stalled item the first time it runs."
        },
        {
          "do": "Run both checks against the piece list.",
          "check": "Every piece has an owner and a date that makes sense."
        }
      ],
      "verifies": [
        "A brief produces a piece list nobody had to type.",
        "Every piece in the kit quotes the same facts as every other piece."
      ],
      "note": "The last package to install, because it is the one that uses all the others.",
      "counts": {
        "skills": 3,
        "agents": 1,
        "templates": 3,
        "guides": 2,
        "checks": 2
      },
      "itemCount": 11,
      "stepCount": 5
    },
    {
      "id": "crm-bridge",
      "name": "CRM Bridge",
      "version": "0.9.0",
      "status": "draft",
      "audience": [
        "sales",
        "operations"
      ],
      "forWhom": "Sales, once it works.",
      "summary": "Reads account records into the workspace so a proposal can name the right contact without anybody retyping it. Not finished, and its prerequisites are wrong.",
      "contains": {
        "skills": [
          {
            "name": "Pull an account",
            "note": "Reads one account record into a work item."
          }
        ],
        "agents": [
          {
            "name": "Contact sync",
            "note": "Nightly. Refreshes contact details on open work items."
          }
        ],
        "templates": [
          {
            "name": "Account record",
            "note": "The fields a proposal needs and nothing else."
          }
        ],
        "guides": [],
        "checks": [
          {
            "name": "Field mapping check",
            "note": "Every field the proposal template needs is mapped to something."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "people-list"
      ],
      "requires": [
        "workspace-foundation",
        "facts-register",
        "partner-portal"
      ],
      "minutes": 40,
      "steps": [
        {
          "do": "Map the account fields.",
          "check": "There is no guide for this step, which is one of the two reasons this package is a draft."
        },
        {
          "do": "Install the pull skill.",
          "check": "Not yet verifiable."
        }
      ],
      "verifies": [
        "Nothing yet. This package has not been installed anywhere successfully."
      ],
      "note": "Draft. It declares Partner Portal as a prerequisite, and Partner Portal declares this one. Two people wrote them in the same fortnight and each assumed the other came first. Selecting either one is what the circular check exists to catch.",
      "counts": {
        "skills": 1,
        "agents": 1,
        "templates": 1,
        "guides": 0,
        "checks": 1
      },
      "itemCount": 4,
      "stepCount": 2
    },
    {
      "id": "partner-portal",
      "name": "Partner Portal",
      "version": "0.9.0",
      "status": "draft",
      "audience": [
        "sales",
        "success"
      ],
      "forWhom": "Partners, eventually.",
      "summary": "A read only view of approved collateral and current prices for a partner network. Not finished, and its prerequisites are wrong.",
      "contains": {
        "skills": [
          {
            "name": "Publish to a partner",
            "note": "Copies an approved piece into a partner readable location."
          }
        ],
        "agents": [
          {
            "name": "Partner refresh",
            "note": "Daily. Republishes anything that changed in approved."
          }
        ],
        "templates": [
          {
            "name": "Partner index",
            "note": "What a partner sees, in the order they see it."
          }
        ],
        "guides": [],
        "checks": [
          {
            "name": "Leak check",
            "note": "Nothing outside approved is reachable from a partner link."
          }
        ]
      },
      "prereqs": [
        "provider-chosen",
        "admin-rights"
      ],
      "requires": [
        "workspace-foundation",
        "approval-route",
        "crm-bridge"
      ],
      "minutes": 45,
      "steps": [
        {
          "do": "Decide what a partner may see.",
          "check": "A written list, not a guess."
        },
        {
          "do": "Install the publish skill.",
          "check": "Blocked on the CRM Bridge, which is blocked on this."
        }
      ],
      "verifies": [
        "Nothing yet. Blocked on a dependency that is blocked on this one."
      ],
      "note": "Draft, and it ships with no guide: the one that was written referenced a CRM Bridge guide that does not exist, so it was pulled. Pairs with CRM Bridge in a dependency loop. Neither can be installed until somebody decides which one comes first, and that decision is a person’s to make, not the planner’s.",
      "counts": {
        "skills": 1,
        "agents": 1,
        "templates": 1,
        "guides": 0,
        "checks": 1
      },
      "itemCount": 4,
      "stepCount": 2
    }
  ]
}
