{
"schema": "actionist.p03.product-primitive-split.v1",
"observed_date": "2026-08-27",
"method_note": "Every row assigned supply_tier in {product, framework, primitive}. product = a runnable application delivering the capability end to end (own UI, data model, identity/permissions, workflow); framework = a substrate you build a product of that kind on (packages/ + examples/ monorepos, mountable engines, starter templates); primitive = a library/SDK/engine implementing part of the capability with no UI, identity or workflow of its own. Primary signal was the existing composite_contents structural field (ui + data + host_chrome => product; no ui => primitive) plus reuse_shape_recommendation. 44 of 200 rows were decided by a live `gh api repos/{owner}/{repo}/contents` read this pass, spent on rows where the structural fields were genuinely ambiguous — chiefly the e_sign and calendar_scheduling rows that motivate this pass, and the CMS/admin-framework boundary (packages/+examples/ monorepo => framework, app dir + migrations + docker-compose => product). The remaining rows were decided from fields already present. Licence class and disposition were NOT re-derived; they are carried unchanged from the survey lane. clean_* counts require license_class in {permissive, permissive-open-core} AND disposition == candidate AND the stated tier. The 'was' baseline in kinds_whose_classification_changed is the tier-blind read this pass replaces: counting every permissive+candidate row as supply regardless of whether it is runnable.",
"per_kind": [
{
"kind": "files_documents",
"total_rows": 27,
"product_rows": 18,
"framework_rows": 2,
"primitive_rows": 7,
"clean_products": 4,
"clean_frameworks": 2,
"clean_primitives": 4,
"product_layer_licence_classes": [
"mixed-copyleft",
"permissive",
"permissive-open-core",
"source-available",
"strong-copyleft",
"strong-copyleft-open-core"
],
"revised_classification": "commodity",
"note": "4 clean permissive products (appwrite/appwrite, owncloud/ocis, pocketbase/pocketbase...) among 18 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "notes_docs",
"total_rows": 23,
"product_rows": 15,
"framework_rows": 6,
"primitive_rows": 2,
"clean_products": 2,
"clean_frameworks": 1,
"clean_primitives": 1,
"product_layer_licence_classes": [
"permissive",
"permissive-open-core",
"source-available",
"strong-copyleft",
"weak-copyleft"
],
"revised_classification": "commodity",
"note": "2 clean permissive products (BookStackApp/BookStack, TryGhost/Ghost) among 15 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "admin_data",
"total_rows": 22,
"product_rows": 8,
"framework_rows": 10,
"primitive_rows": 4,
"clean_products": 1,
"clean_frameworks": 5,
"clean_primitives": 3,
"product_layer_licence_classes": [
"permissive",
"source-available",
"strong-copyleft",
"strong-copyleft-open-core"
],
"revised_classification": "scarce",
"note": "Exactly one clean permissive product (appsmithorg/appsmith) among 8 product row(s); single point of dependence."
},
{
"kind": "auth_identity",
"total_rows": 19,
"product_rows": 8,
"framework_rows": 4,
"primitive_rows": 7,
"clean_products": 6,
"clean_frameworks": 4,
"clean_primitives": 5,
"product_layer_licence_classes": [
"permissive",
"strong-copyleft"
],
"revised_classification": "commodity",
"note": "6 clean permissive products (appwrite/appwrite, authelia/authelia, casdoor/casdoor...) among 8 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "billing",
"total_rows": 17,
"product_rows": 13,
"framework_rows": 3,
"primitive_rows": 1,
"clean_products": 2,
"clean_frameworks": 3,
"clean_primitives": 1,
"product_layer_licence_classes": [
"permissive",
"source-available",
"strong-copyleft",
"weak-copyleft"
],
"revised_classification": "commodity",
"note": "2 clean permissive products (TryGhost/Ghost, al1abb/invoify) among 13 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "crm",
"total_rows": 17,
"product_rows": 14,
"framework_rows": 3,
"primitive_rows": 0,
"clean_products": 2,
"clean_frameworks": 3,
"clean_primitives": 0,
"product_layer_licence_classes": [
"permissive",
"strong-copyleft",
"strong-copyleft-open-core",
"weak-copyleft"
],
"revised_classification": "commodity",
"note": "2 clean permissive products (marmelab/atomic-crm, pdovhomilja/nextcrm-app) among 14 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "inventory",
"total_rows": 17,
"product_rows": 12,
"framework_rows": 5,
"primitive_rows": 0,
"clean_products": 3,
"clean_frameworks": 1,
"clean_primitives": 0,
"product_layer_licence_classes": [
"permissive",
"strong-copyleft",
"weak-copyleft"
],
"revised_classification": "commodity",
"note": "3 clean permissive products (inventree/InvenTree, open-mercato/open-mercato, saleor/saleor) among 12 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "messaging_notifications",
"total_rows": 16,
"product_rows": 15,
"framework_rows": 0,
"primitive_rows": 1,
"clean_products": 6,
"clean_frameworks": 0,
"clean_primitives": 1,
"product_layer_licence_classes": [
"mixed-copyleft",
"permissive",
"permissive-open-core",
"source-available",
"strong-copyleft",
"strong-copyleft-open-core"
],
"revised_classification": "commodity",
"note": "6 clean permissive products (TryGhost/Ghost, activepieces/activepieces, chatwoot/chatwoot...) among 15 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "analytics_bi",
"total_rows": 15,
"product_rows": 12,
"framework_rows": 1,
"primitive_rows": 2,
"clean_products": 2,
"clean_frameworks": 1,
"clean_primitives": 2,
"product_layer_licence_classes": [
"permissive",
"permissive-open-core",
"strong-copyleft",
"strong-copyleft-open-core"
],
"revised_classification": "commodity",
"note": "2 clean permissive products (apache/superset, umami-software/umami) among 12 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "calendar_scheduling",
"total_rows": 15,
"product_rows": 10,
"framework_rows": 0,
"primitive_rows": 5,
"clean_products": 2,
"clean_frameworks": 0,
"clean_primitives": 4,
"product_layer_licence_classes": [
"permissive",
"strong-copyleft",
"weak-copyleft"
],
"revised_classification": "commodity",
"note": "2 clean permissive products (calcom/cal.diy, rbbydotdev/someday) among 10 product row(s) — deploy one and ship; selection problem, not sourcing.",
"qualification": "clean_products=2 depends on counting rbbydotdev/someday as a full product; it is runnable and self-hostable but Gmail/Apps-Script-bound. Under a stricter product definition clean_products=1 and revised_classification=scarce."
},
{
"kind": "approvals_workflow",
"total_rows": 14,
"product_rows": 9,
"framework_rows": 0,
"primitive_rows": 5,
"clean_products": 3,
"clean_frameworks": 0,
"clean_primitives": 2,
"product_layer_licence_classes": [
"permissive",
"permissive-open-core",
"source-available",
"strong-copyleft",
"strong-copyleft-open-core"
],
"revised_classification": "commodity",
"note": "3 clean permissive products (activepieces/activepieces, apache/airflow, kestra-io/kestra) among 9 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "case_workflow",
"total_rows": 13,
"product_rows": 7,
"framework_rows": 1,
"primitive_rows": 5,
"clean_products": 0,
"clean_frameworks": 1,
"clean_primitives": 1,
"product_layer_licence_classes": [
"permissive-open-core",
"strong-copyleft",
"weak-copyleft"
],
"revised_classification": "product_layer_missing_under_permissive_terms",
"note": "7 runnable product(s) exist but every one is permissive-open-core/strong-copyleft/weak-copyleft; the 1 clean permissive row(s) (flowable/flowable-engine) are primitives you must build the product around."
},
{
"kind": "project_management",
"total_rows": 13,
"product_rows": 13,
"framework_rows": 0,
"primitive_rows": 0,
"clean_products": 2,
"clean_frameworks": 0,
"clean_primitives": 0,
"product_layer_licence_classes": [
"permissive",
"permissive-open-core",
"source-available",
"strong-copyleft",
"strong-copyleft-open-core",
"weak-copyleft"
],
"revised_classification": "commodity",
"note": "2 clean permissive products (kanboard/kanboard, pdovhomilja/nextcrm-app) among 13 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "airtable_data",
"total_rows": 11,
"product_rows": 9,
"framework_rows": 2,
"primitive_rows": 0,
"clean_products": 3,
"clean_frameworks": 2,
"clean_primitives": 0,
"product_layer_licence_classes": [
"permissive",
"permissive-open-core",
"source-available",
"strong-copyleft",
"strong-copyleft-open-core"
],
"revised_classification": "commodity",
"note": "3 clean permissive products (appwrite/appwrite, pocketbase/pocketbase, supabase/supabase) among 9 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "e_sign",
"total_rows": 11,
"product_rows": 5,
"framework_rows": 0,
"primitive_rows": 6,
"clean_products": 0,
"clean_frameworks": 0,
"clean_primitives": 3,
"product_layer_licence_classes": [
"strong-copyleft",
"strong-copyleft-open-core"
],
"revised_classification": "product_layer_missing_under_permissive_terms",
"note": "5 runnable product(s) exist but every one is strong-copyleft/strong-copyleft-open-core; the 3 clean permissive row(s) (vbuch/node-signpdf, MatthiasValvekens/pyHanko, digitorus/pdfsign) are primitives you must build the product around."
},
{
"kind": "forms",
"total_rows": 11,
"product_rows": 10,
"framework_rows": 0,
"primitive_rows": 1,
"clean_products": 1,
"clean_frameworks": 0,
"clean_primitives": 1,
"product_layer_licence_classes": [
"permissive",
"strong-copyleft",
"strong-copyleft-open-core",
"weak-copyleft"
],
"revised_classification": "scarce",
"note": "Exactly one clean permissive product (al1abb/invoify) among 10 product row(s); single point of dependence."
},
{
"kind": "search",
"total_rows": 11,
"product_rows": 3,
"framework_rows": 0,
"primitive_rows": 8,
"clean_products": 1,
"clean_frameworks": 0,
"clean_primitives": 3,
"product_layer_licence_classes": [
"permissive",
"source-available",
"strong-copyleft"
],
"revised_classification": "scarce",
"note": "Exactly one clean permissive product (supabase/supabase) among 3 product row(s); single point of dependence."
},
{
"kind": "support_desk",
"total_rows": 10,
"product_rows": 10,
"framework_rows": 0,
"primitive_rows": 0,
"clean_products": 1,
"clean_frameworks": 0,
"clean_primitives": 0,
"product_layer_licence_classes": [
"permissive",
"permissive-open-core",
"source-available",
"strong-copyleft",
"weak-copyleft"
],
"revised_classification": "scarce",
"note": "Exactly one clean permissive product (chatwoot/chatwoot) among 10 product row(s); single point of dependence."
},
{
"kind": "e_commerce",
"total_rows": 8,
"product_rows": 3,
"framework_rows": 5,
"primitive_rows": 0,
"clean_products": 2,
"clean_frameworks": 1,
"clean_primitives": 0,
"product_layer_licence_classes": [
"permissive"
],
"revised_classification": "commodity",
"note": "2 clean permissive products (open-mercato/open-mercato, saleor/saleor) among 3 product row(s) — deploy one and ship; selection problem, not sourcing."
},
{
"kind": "lms",
"total_rows": 7,
"product_rows": 7,
"framework_rows": 0,
"primitive_rows": 0,
"clean_products": 1,
"clean_frameworks": 0,
"clean_primitives": 0,
"product_layer_licence_classes": [
"permissive",
"strong-copyleft"
],
"revised_classification": "scarce",
"note": "Exactly one clean permissive product (oppia/oppia) among 7 product row(s); single point of dependence."
},
{
"kind": "field_ops",
"total_rows": 5,
"product_rows": 5,
"framework_rows": 0,
"primitive_rows": 0,
"clean_products": 0,
"clean_frameworks": 0,
"clean_primitives": 0,
"product_layer_licence_classes": [
"strong-copyleft",
"weak-copyleft"
],
"revised_classification": "product_layer_missing_under_permissive_terms",
"note": "5 runnable product(s) exist but every one is strong-copyleft/weak-copyleft; there are no clean permissive rows at all, not even primitives."
},
{
"kind": "connectors",
"total_rows": 4,
"product_rows": 2,
"framework_rows": 0,
"primitive_rows": 2,
"clean_products": 1,
"clean_frameworks": 0,
"clean_primitives": 0,
"product_layer_licence_classes": [
"permissive-open-core",
"source-available"
],
"revised_classification": "scarce",
"note": "Exactly one clean permissive product (activepieces/activepieces) among 2 product row(s); single point of dependence."
},
{
"kind": "portal",
"total_rows": 2,
"product_rows": 2,
"framework_rows": 0,
"primitive_rows": 0,
"clean_products": 0,
"clean_frameworks": 0,
"clean_primitives": 0,
"product_layer_licence_classes": [
"strong-copyleft",
"weak-copyleft"
],
"revised_classification": "UNDERDETERMINED",
"note": "Only 2 row(s) surveyed; too thin to classify."
},
{
"kind": "developer_docs_rendering",
"total_rows": 1,
"product_rows": 0,
"framework_rows": 0,
"primitive_rows": 1,
"clean_products": 0,
"clean_frameworks": 0,
"clean_primitives": 0,
"product_layer_licence_classes": [],
"revised_classification": "UNDERDETERMINED",
"note": "Only 1 row(s) surveyed; too thin to classify."
}
],
"kinds_whose_classification_changed": [
{
"kind": "admin_data",
"was": "commodity",
"now": "scarce",
"why": "9 permissive+candidate row(s) looked like supply, but only 1 of them is a runnable product (3 primitive, 5 framework); product rows are permissive/source-available/strong-copyleft/strong-copyleft-open-core"
},
{
"kind": "case_workflow",
"was": "commodity",
"now": "product_layer_missing_under_permissive_terms",
"why": "2 permissive+candidate row(s) looked like supply, but only 0 of them is a runnable product (1 primitive, 1 framework); product rows are permissive-open-core/strong-copyleft/weak-copyleft"
},
{
"kind": "e_sign",
"was": "commodity",
"now": "product_layer_missing_under_permissive_terms",
"why": "3 permissive+candidate row(s) looked like supply, but only 0 of them is a runnable product (3 primitive, 0 framework); product rows are strong-copyleft/strong-copyleft-open-core/weak-copyleft"
},
{
"kind": "forms",
"was": "commodity",
"now": "scarce",
"why": "2 permissive+candidate row(s) looked like supply, but only 1 of them is a runnable product (1 primitive, 0 framework); product rows are permissive/strong-copyleft/strong-copyleft-open-core/weak-copyleft"
},
{
"kind": "search",
"was": "commodity",
"now": "scarce",
"why": "4 permissive+candidate row(s) looked like supply, but only 1 of them is a runnable product (3 primitive, 0 framework); product rows are permissive/source-available/strong-copyleft"
},
{
"kind": "field_ops",
"was": "missing",
"now": "product_layer_missing_under_permissive_terms",
"why": "0 permissive+candidate row(s) looked like supply, but only 0 of them is a runnable product (0 primitive, 0 framework); product rows are strong-copyleft/weak-copyleft"
}
],
"summary": {
"total_rows": 200,
"product": 134,
"framework": 20,
"primitive": 46,
"kinds_reclassified": 6,
"kinds_now_product_layer_missing": [
"case_workflow",
"e_sign",
"field_ops"
]
},
"lane_owner_corrections": [
{
"repo": "Keyfactor/signserver-ce",
"was": "product",
"now": "primitive",
"why": "Subagent's own evidence said 'not a DocuSign-class signer-workflow app... no document-sending workflow' — that is a primitive. Signing-authority/HSM infrastructure, not an e-signature product.",
"effect": "e_sign products 6 -> 5; classification unchanged (clean_products was and remains 0)."
}
],
"note_regeneration": {
"reason": "CENA verifier found e_sign.note asserting '6 runnable products' while product_rows=5 after correction J-02. All per-kind notes are now generated deterministically from their own counters — including the named repos, which are the useful part — so prose can never drift from the numbers again. UNDERDETERMINED kinds keep their 'too thin to classify' wording.",
"notes_regenerated": 24,
"notes_changed_vs_original": 24
}
}P03 · Supply · Rendered from source
product primitive split
Curated capability shelf