P08 · Experience · Rendered from source

decision ledger

Archetypes, shells and layouts

223 lines15,967 bytessha256 1a4ae46bf996
{
  "part": "P08",
  "run_id": "2026-08-27-sprint-1-fable",
  "observed": "2026-08-27",
  "mode": "research-only",
  "status": "UNEXECUTED / NOT_ADMITTED",
  "note": "No decision here is authorized or admitted. 'recommended' means recommended to a decision-maker, not taken.",
  "decisions": [
    {
      "id": "D-P08-01",
      "question": "Verdict on A15, the inherited five-area ISSO shell",
      "verdict": "Reject as a default; retain as one archetype-level rail variant. Reclassify A15 from 'unproven' to 'partially falsified at the semantic level'.",
      "evidence_class": "observed",
      "evidence": [
        "sidebar-factory.tsx:19-25 types sections as a fixed five-element tuple ('Must be exactly 5 sections')",
        "page-registry.tsx:6 freezes five product ids",
        "sidebar-factory.tsx:27-34 fixed hotkeys Cmd1-Cmd5",
        "agency vs model rails assign 'recon' to both Team and Tasks, and 'content-gen' to both Tools and Insights",
        "ISSO app has 8+ top-level route groups; portal/ alone holds 20+ routes no five-slot rail reaches",
        "autosaas-method.md:283 records 'no generic ISSO shell extraction'"
      ],
      "what_survives": "Five as a soft BUDGET CAP on top-level rail items, consistent with IBM Carbon's published >5 rule. Not as a schema.",
      "gate": "E1 card-sort / first-click test, 3 case_workflow industries, 15 practitioners, paper navs only",
      "falsifier": "If the five-slot nav scores within noise of a spine-derived nav on first-click accuracy, keep five slots and spend the budget elsewhere.",
      "disposition": "recommended"
    },
    {
      "id": "D-P08-02",
      "question": "Top shell option",
      "verdict": "Option 1 - host-owned page shelf with donors as embedded surfaces (25/30). Runner-up: joint at 19/30 between Option 2 (host rail + donor nav registry injection) and Option 4 (archetype-native topology), which are complementary rather than competing - O2 is a mechanism, O4 is a topology.",
      "evidence_class": "observed",
      "evidence": [
        "FROZEN-PAGE-SKELETON.md: 11 host-owned pages, ~20 donors folded beneath, zero donor-named nav entries, status FROZEN",
        "OWNERSHIP-AND-DATA-LAYER-DECISIONS.md:96 'Shell / navigation rail -> OWN. Already replaced Plane's launcher'",
        "Luigi is the OSS embodiment: host declares every nav node, donor contributes no chrome"
      ],
      "limitations": "Option 1's feasibility rests on donors rendering below full-page, which is UNTESTED. This is its weakest joint.",
      "gate": "E3 donor admission test",
      "falsifier": "If most donors cannot render below full-page, Option 1 collapses toward Option 5 (iframe) or Option 6 (headless) and P08's cost model changes materially.",
      "disposition": "recommended"
    },
    {
      "id": "D-P08-03",
      "question": "Host-shell vs donor-chrome boundary",
      "verdict": "Host MUST own eight surfaces: identity/session, tenant switch, the navigation rail, settings entry point, global search, notifications, cross-app navigation and the URL space, and theming tokens. Donor MAY keep internal below-the-fold nav, its own record routing under a host basename, its data model and migrations in its own schema, and its engine-shaped internals.",
      "evidence_class": "observed",
      "evidence": [
        "TEABLE-ABSORPTION-BRIEF success criteria 1 and 4 require no donor login prompt and no reachable donor signup route",
        "Luigi: host holds the OIDC session, donor calls LuigiClient.getToken()",
        "Backstage RouteRef/ExternalRouteRef so donors never hardcode host URLs",
        "Grafana /a/<id>/* nesting lets a donor keep hierarchy below one host row",
        "OWNERSHIP-AND-DATA-LAYER-DECISIONS: one Postgres server, separate schemas, one owner per table"
      ],
      "rationale": "A donor answering 'who am I here' creates a second identity; a donor answering 'where do I go next' creates a URL the host cannot honour. Both are correctness failures, not styling failures.",
      "disposition": "recommended-as-contract"
    },
    {
      "id": "D-P08-04",
      "question": "Absorb-vs-preserve rule for donor navigation",
      "verdict": "Absorb the navigation when the donor supplies a CAPABILITY; preserve it when the donor supplies a DESTINATION. At most one or two destinations per product. Governance corollary: donors declare intent (label, icon, routeRef); the host declares order - never a numeric position.",
      "evidence_class": "observed",
      "evidence": [
        "TEABLE-ABSORPTION-BRIEF: 'Teable is NOT a page'; 'The broker never clicks Tables'; a separate page 'becomes a second silo nobody updates'",
        "FROZEN-PAGE-SKELETON: exactly one whole-slice donor (Tasks = Plane) out of ~20",
        "WordPress $position integer produces silent collisions patched by an MD5 hash offset",
        "Grafana addToNav boolean and Shopify s-app-nav are declarative",
        "P08-SR-056/057 + sisocrm-donor-absorption.md: Teable is the purest data-model donor and got a NATIVE non-iframe mount — the opposite of the prediction, on the exact donor the prediction is about. The recorded reason is not semantic: THEMING-CONTRACT.md:94-102 states 'A cross-origin iframe is a hard CSS boundary — custom properties do not inherit across it... This is the concrete reason the iframe had to go.' Teable-the-grid and Postiz-the-scheduler are both 'capabilities' under the old vocabulary, yet one is absorbed and one iframed; capability-vs-destination does not discriminate them, cascade-and-session coupling does."
      ],
      "absorb_signals": [
        "donor surface is product-defining",
        "donor nav names the vendor, not the work",
        "donor covers only part of one host page",
        "two donors would claim the same concept",
        "donor identity would create a second login",
        "donor is already headless or chrome-light"
      ],
      "preserve_signals": [
        "donor is a whole workflow users know by name and its internal nav IS the expertise",
        "donor nav sits below the host rail rather than beside it",
        "donor is security/legally critical and forking its UI forks its audit story",
        "the LICENCE forbids chrome removal",
        "donor is untrusted or multi-tenant-risky"
      ],
      "reframe": "Navigation absorption is a data-integrity decision disguised as a layout decision - two nav entries over one concept produce two lists over one dataset.",
      "disposition": "recommended-as-contract",
      "status": "REVISED — original rule falsified by the SISOCRM estate",
      "chosen": "SUPERSEDED. Original: 'absorb when the donor supplies a CAPABILITY, preserve when it supplies a DESTINATION; data-model nav preserved in-pane, workflow nav absorbed.' REPLACEMENT, derived from the only built estate: ABSORB (native mount) when the surface must share the host's CSS CASCADE or its SESSION; PRESERVE (iframe) when the surface is self-contained and a hard boundary costs nothing. The axis is MECHANICAL, not semantic.",
      "confidence": "medium — replacement rule is inferred from one built estate (n=1), but it is the only estate that has actually made these decisions under real constraints",
      "falsifier": "Find a donor absorbed natively that needed NEITHER the host cascade NOR the host session, or one iframe-preserved despite requiring both. Either would break the mechanical rule.",
      "what_survives": "The NAV half of the original rule holds unanimously: no donor's own navigation was ever adopted into the rail — it is 100% host-authored and donor chrome is actively suppressed via data-siso-hide patches. Narrowed to 'never inherit donor nav', the estate confirms it. It is the absorb/preserve MECHANISM choice that was mispredicted."
    },
    {
      "id": "D-P08-05",
      "question": "Verdict on the 20/80 host/app pane",
      "verdict": "The concept is sound and precedented; the NUMBER is not evidenced. Specify a pixel width with a viewport-class collapse rule, never a percentage. Starting specification (hypothesis): 320px host rail at >=1056px, icon rail ~48-80px below that, bottom bar or overlay below ~768px.",
      "evidence_class": "observed",
      "evidence": [
        "Across 19 measured shells every rail is a fixed pixel constant; Carbon's 256px is 20% at 1280px and 13% at 1920px",
        "VS Code layout.ts:3026 min(300, viewport/4) is the only proportional rule in the corpus - and it is 25/75, capped",
        "320px corroborated three times within 4px: Zendesk 320, Grafana 320, Metabase 324",
        "Polaris and Primer both switch at 768px; Material 3 switches by window size class"
      ],
      "limitations": "No vendor publishes a rationale for its width. IBM Carbon alone publishes a decision RULE (left panel when >5 secondary items; no third tier).",
      "gate": "E2 rail collapse-rate test, 3-4 weeks, per-user memory, no prompt",
      "falsifier": ">50% permanent collapse kills the wide rail in favour of an icon rail. If the only items ever clicked are settings and tenant-switch, the rail should be a puck.",
      "disposition": "recommended"
    },
    {
      "id": "D-P08-06",
      "question": "Which archetypes cover 80% of the first 17 industries",
      "verdict": "Under strict reading there is no cheap answer, and that is the finding. Primary-only: 5 archetypes reach 82.4% (case_workflow, field_operations, learning_content, scheduling, crm). Requiring BOTH primary and secondary: no subset of 7 or fewer reaches 80% (best 7 = 13/17, 76%); 8 give 15/17 (88%); 9 give 17/17. case_workflow + portal TOUCH 11/17 (65%) but SATISFY only 4/17 (24%).",
      "evidence_class": "observed",
      "evidence": [
        "Computed this run from the b2b shelf 17-industry primary/secondary mapping",
        "Six industries touch neither case_workflow nor portal: construction, ecommerce, hospitality, logistics_freight, real_estate, saas"
      ],
      "limitations": "The arithmetic is exact; the inputs are I-class judgement from the b2b shelf, not measured demand.",
      "build_order": "case_workflow first, portal second - justified by the demand/supply inversion (highest demand, thinnest clean-licence supply), NOT by a coverage argument. Do not build marketplace: primary for none, secondary for none.",
      "disposition": "recommended"
    },
    {
      "id": "D-P08-07",
      "question": "Which nav absorption mechanisms are eliminated",
      "verdict": "Reverse-proxy chrome stripping is rejected. iframe isolation is fallback-only. Any option premised on donor CSS surviving intact, donor modals covering the viewport, or one shared React tree is mispriced.",
      "evidence_class": "observed",
      "evidence": [
        "qiankun v3: styleIsolation is 'a one-way boundary' - stops donor CSS escaping, does not stop host CSS entering; JS sandbox 'not a security boundary for running untrusted code'",
        "qiankun v3: a menu/dialog/tooltip portaled to document.body falls outside the scope root and its scoped selectors will not match",
        "wujie: in an iframe modals 'can only display inside the iframe and cannot cover the whole page'",
        "Module Federation singleton defaults to false and ships a Bridge for framework isolation",
        "Apache 'will not rewrite URL references inside HTML pages' by default; mod_proxy_html 'has no knowledge of what is a URL within an embedded script'; runtime-generated URLs have no documented fix",
        "MDN: SameSite=Lax excludes iframe navigations; Firefox partitions since 103; Storage Access API requires transient user activation"
      ],
      "disposition": "recommended"
    },
    {
      "id": "D-P08-08",
      "question": "Is licence a shell constraint",
      "verdict": "Yes, and the gate belongs BEFORE design work. Stripping donor chrome is an engineering task until it is a licence violation. Read the LICENSE body, never the badge.",
      "evidence_class": "observed",
      "evidence": [
        "NocoBase LICENSE.txt 5.2 forbids removing or changing NocoBase branding on the interface except the top-left logo",
        "Directus is MSCL-1.0-GPL, forbids circumventing the licence key, GPL-3.0 only on the fourth anniversary",
        "28 of 104 repos returned NOASSERTION; reading bodies moved verdicts in both directions - single-spa is plain MIT that GitHub failed to classify",
        "Directory-scoped open-core (ee/, enterprise/, premium/, x-pack) means a surface lifted from an ee/ path breaches regardless of the top-level licence"
      ],
      "disposition": "recommended-as-contract"
    },
    {
      "id": "D-P08-09",
      "question": "Status of A34 (host can absorb donor identity/settings/navigation cleanly)",
      "verdict": "Remains UNKNOWN. No donor was mounted in this run. A34 is now well-specified and gated behind E3, which is progress of a different kind but is not evidence.",
      "evidence_class": "unknown",
      "gate": "E3 donor admission test: six donors x four binary questions answered by real attempts, 1 day per donor",
      "disposition": "open"
    },
    {
      "id": "P08-D10",
      "question": "What does adaptation actually cost, and is assumption A07 ('always only 1-2% of the work') true?",
      "options_considered": [
        "A07 true as stated",
        "A07 false as stated",
        "A07 true within a bounded region"
      ],
      "chosen": "A07 is FALSE as a universal and roughly TRUE for iframe-preserved donors only. Cost splits by absorption depth, not by donor.",
      "evidence": [
        "P08-SR-057 (lane-owner verified): iframe preservation 17-62 patch lines; identity+data-layer absorption 273 lines across 9 files including a changed PUBLIC API validation regex",
        "ABSORPTION-STRATEGY.md:111-119 'Rewriting a data layer per donor means their models onto our schema, their queries, their migrations, their background jobs, their file handling. Not a weekend each.'"
      ],
      "confidence": "medium-high on the gradient; low on absolute effort",
      "falsifier": "Diff .teable-runtime against pinned upstream 06a4461e2bc53055182d4df0a72dffa26fd99210 for true total divergence; if it is close to 273 lines the patch files are the whole story, if far larger the gradient is steeper still",
      "note": "NO hour or effort data exists anywhere in the estate. This team measured adaptation cost in DIFF SURFACE against upstream — arguably the better metric for upgrade friction. 'No hours were ever recorded' is itself the finding."
    }
  ],
  "gates_in_order": [
    {
      "id": "E3",
      "name": "Donor admission test",
      "rank": 1,
      "cost": "6 engineer-days",
      "blocks": "D-P08-02, A34"
    },
    {
      "id": "E1",
      "name": "Five-area card sort",
      "rank": 2,
      "cost": "15 practitioners, paper only",
      "blocks": "D-P08-01, A15"
    },
    {
      "id": "E2",
      "name": "Rail collapse-rate",
      "rank": 3,
      "cost": "a toggle and an event, 3-4 weeks",
      "blocks": "D-P08-05"
    },
    {
      "id": "E4",
      "name": "Vocabulary-isomorphism test",
      "rank": 4,
      "cost": "desk research + expert interviews",
      "blocks": "per-industry template strategy"
    },
    {
      "id": "E5",
      "name": "Licence gate",
      "rank": 5,
      "cost": "near zero",
      "blocks": "any donor chrome work"
    }
  ],
  "not_established": [
    "No user was tested",
    "No donor was mounted",
    "No shell was built or measured",
    "No published evidence found linking nav topology or area count to task success in any surveyed product - absence reported, not filled",
    "87 of 111 commercial products are inferred, not verified this session",
    "Bykonz directory contents were not read",
    "SISOCRM shell read as documents, not running code",
    "Matrix scores are judgement, not measurement",
    "No accessibility, performance, i18n/RTL or security review"
  ]
}