Skip to content

docs: decide what 1.0 freezes where the contract document does not say #343

Closed

Description

@schlessera

Context

Part of #56. Found by the 1.0 surface audit (#319), against main @ 550a41ef.

#56 says 1.0 "is not a promise of stability for anything not in the contract
document". The audit found surfaces where that sentence does not settle the
answer: the contract document is silent, contradicts another document, or
defers to a document outside itself. Each needs a ruling before 1.0, because
the answer decides which follow-up work exists. The first question also decides
whether the lockstep fixed group can survive 1.0.

  1. What triggers a major — ruled 2026-09-28 (C). Before 1.0, audit and reduce ordinary public exports to the deliberately supported surface, then stabilize that surface, including all types reachable through public signatures and its documented behavior. Remove accidental exposure or move unavoidable cross-package helpers to clearly named internal entry points with explicit compatibility exclusions. Align package entry points and the contract rather than retaining an ambiguous disclaimer over ordinary public exports. Breaking the chosen public surface after 1.0 requires a major. This does not change lockstep, schedule 1.0, or freeze experimental interfaces now. Exact classifications depend on the remaining rulings below. Implementation and the durable decision record are tracked in packages: curate public exports and align the 1.0 stability contract #534.
  2. Backend helper toolkit — ruled 2026-09-28 (B). Stabilize a small documented backend-authoring toolkit at 1.0, including approval requests and edited-input validation (requestToolPermission, checkEditedApproval) and their required public types. Audit other helpers by their external authoring role. Keep backend-specific tool lists, subprocess environment policy tables and incidental helpers internal. Public configurable-policy formats and documented behavior are stable; the bundled default entries may evolve without being treated as immutable constants, while still respecting documented behavioral guarantees. The concrete inventory and decision record are tracked in ui-sdk: define the supported backend-authoring toolkit before 1.0 #535, coordinated with packages: curate public exports and align the 1.0 stability contract #534's export cleanup. This does not freeze interfaces immediately.
  3. DocumentRenderer — ruled 2026-09-28 (A). Internal adapter type, not a public extension interface. The unchanged type now lives beside the optional Puppeteer loader and is marked @internal (DocumentRenderer, packages/core/src/providers/renderers/puppeteer.ts:12-16; resolveDocumentRenderer, packages/core/src/providers/renderers/puppeteer.ts:37-56). It remains absent from core's public entry points. Do not add provider injection or freeze the type at 1.0. Public CLI rendering behavior and the Puppeteer package API are unaffected. core: classify DocumentRenderer as an internal adapter #536 delivered the cleanup and indexed durable record through merged refactor(core): classify DocumentRenderer as an internal adapter #668.
  4. Module authoring — ruled 2026-09-28 (A). Stabilize the deliberately public module-authoring API at 1.0; it remains experimental until then. Cover defineModule, manifest/contribution shapes, command/hygiene contexts, signature-reachable types and documented lifecycle. Resolve ui: module settings screens, rendered from settings each module declares (jobs criteria and sources first) #528's structural settings implications and core: decide whether a module may contribute MCP tools, and whether they are contract surface #59's module-MCP direction before freezing, without making every prospective additive feature a prerequisite for 1.0. No release date or immediate freeze is selected. Follow-up: core: define the module-authoring stability contract for 1.0 #537.
  5. The wire protocol — ruled 2026-09-28 (A). The client/server wire protocol is a machine compatibility contract now, not an experimental extension interface. Apply existing versioning rules: additive changes ship in minors; before 1.0, breaks require a prior maintainer ruling, the breaking label, and a changeset naming the break, and ship in minors; from 1.0, breaks require a major. Contract changes require a CONTRACT: commit and same-commit contract update. This is not an immediate freeze. Revision negotiation does not waive documented compatibility guarantees or versioning requirements. The protocol header (COMPATIBILITY CONTRACT, packages/ui-sdk/src/protocol.ts:5-8), revision-negotiation contract, explicit seam list and extension guide now agree. docs: clarify wire protocol compatibility and versioning #538 delivered the durable classification record through merged CONTRACT: docs(protocol): clarify compatibility and versioning #670, preserving the existing negotiation and validation promises.
  6. HTTP routes — ruled 2026-09-28 (A). Curate an explicit supported HTTP API before 1.0. Inventory mounted routes, classify those intended for independent clients/integrations as supported, and explicitly mark the rest internal. Preserve existing documented promises and account for supported SDK functionality. Specify authentication/authorization, inputs, outputs, errors and observable behavior, not just URLs. Supported routes follow the existing machine-contract versioning policy. This does not freeze all current routes or implicitly choose the final inventory; proposed consolidations that break existing promises require their own ruling before implementation. docs: inventory and define the supported HTTP API before 1.0 #539 delivered the complete inventory and supported specifications and durable boundary record through merged CONTRACT: define the supported HTTP API and internal route inventory #704. ui-server: restore promised four-decimal activity rollup cost sums #692's four-decimal activity-rollup correction is delivered by merged #796, squash a408a0f34707b5b3845bbe8b0092ca86f76d016d, verified on main with the exact tested tree. The current specification preserves raw stats and stored precision. The real HTTP inventory/coverage is delivered by #691/#803, with named mounting and mutation evidence. Non-object JSON validation is delivered by #694/#797. The client/type follow-ups are delivered: ui-react: align the exported health and sync helpers with actual HTTP responses #693/CONTRACT: fix(ui-react): align health and sync helpers with HTTP responses #926 and core: reconcile nullable result tags with the public SearchResult type #702/CONTRACT: correct nullable search and reranker tags #928. CONTRACT: correct nullable search and reranker tags #928’s approved nullable declaration correction is merged as ae61e8271dfd10b43a447248fcc3a538f4cccb1e, verified on main; runtime values remain unchanged.
  7. brain.db SQL — ruled 2026-09-28 (B). Make the SQL schema internal before 1.0, replacing supported direct readers with deliberate query APIs and keeping schema versions for internal compatibility checks. Current direct-SQL guarantees remain binding until suitable replacements and consumer transitions are implemented. Centralize query ownership and compatibility handling; preserve efficient graph access (in-process APIs are an acceptable approach, not a requirement for subprocess-per-query calls or a new service). Supported query APIs follow the existing contract-versioning policy. Internal schema changes must still handle shipped consumers and version skew safely. Markdown remains authoritative and brain.db disposable. core: design supported query APIs to replace the public SQL contract #540 delivered the query design and durable Q7 record through merged docs: design supported content-index query APIs #703. The supported query result API is delivered by core: implement supported content-index query result APIs #695/CONTRACT: feat(core): add supported content-index queries #755; see the shipped specification. The pi graph/list migration is delivered by ui-backend-pi: replace direct index link and listing reads with query results #698 through merged #760, squash 2480efe13db35a75884c1ead6f73e11dfb6241cf, verified on main. The optional core peer and core-created root-bound query context are approved by both dated core: settle index-query package access and module context replacement #696 rulings and durably recorded by docs: record approved index-query package and hygiene boundaries #911/docs: record approved index-query package and hygiene boundaries #936, squash 10d435675c7eff19afbfb75a432a14809c162f55, verified on main. Current decision and design include absence/skew, reachable types, authoritative root binding and breaking-migration conditions. core: settle index-query package access and module context replacement #696 completes the policy reconciliation; remaining runtime migration, coverage and retirement work is ui-server: move graph and voice reads onto supported core query results #697, core: replace module hygiene raw database exposure with query results #699, core: guard supported index queries across actual package consumers #700 and docs: retire direct brain.db SQL guarantees after query migration #701. Existing direct-SQL guarantees remain binding until the verified transition.
  8. Configuration and module formats — ruled 2026-09-28 (A). Inventory deliberately supported brain.config keys, environment inputs, module JSON settings (including ui: module settings screens, rendered from settings each module declares (jobs criteria and sources first) #528) and canonical module content formats under one compatibility policy. Keep caches/internal storage layouts excluded. Specify meaning, validation, precedence and defaults, distinguishing defaults explicitly allowed to evolve (such as curated board selections) from promised behavior; no blanket exemption for documented behavioral breaks. Module-owned specifications may hold details under the shared policy. Clean up before 1.0; supported input breaks follow the existing versioning rules. Preserve current documented promises during cleanup. Inventory, documentation and durable record: docs: define compatibility for configuration and module formats #542.

The audit's position on the lockstep group depends on question 1. It is posted
on #56 with the audit table.

Scope

  • A maintainer ruling on each question, as a comment here in the
    **Decision (maintainer, <date>):** form.
  • The rulings that bind 1.0 recorded in docs/decisions/contract-versioning.md
    or a new record beside it.
  • One follow-up task per ruling that needs work, attached to Epic: 1.0.0 — the stability bar #56.

Out of scope

  • Implementing any ruling.
  • The documented seams. Each has its own issue or is ready.
  • Scheduling 1.0.

Acceptance criteria

  • Each of the eight questions has a recorded ruling. "Out of the contract,
    and the doc says so" is an acceptable answer.
  • The rulings on questions 1 and 5 are in docs/decisions/.
  • Follow-up tasks are filed and attached to Epic: 1.0.0 — the stability bar #56, or the ruling says none is
    needed.

Verification

Each question has a dated ruling, and each ruling either links a follow-up
issue or says none is needed.

Contract impact

  • This touches the integration contract, so it needs the contract label, a CONTRACT: commit prefix, and the doc updated in the same commit.
  • This changes a published package's behaviour, so it needs a changeset.

The rulings change nothing by themselves. Their follow-ups will touch the
contract.

Remaining completion dependency

All eight maintainer rulings and their follow-up tasks are recorded. Q5 is durably recorded by #538/#670 in docs/decisions/contract-versioning.md. Q1 is now durably recorded too: #534 merged as PR #1052 (825cd044) with docs/decisions/public-export-boundary.md, which opens "Decided 2026-09-28 by the maintainer (#343 question 1)" and is indexed in docs/decisions/README.md. No dependency remains. What is left is to verify both records against the Q1 and Q5 rulings above, check the combined criterion, and close this tracking issue. Surfaces #534 deliberately left public are ruled in #1053, which does not block this issue.

Updated 2026-09-28: all eight questions ruled; follow-ups #534–#540 and #542 attached to #56. Removed needs: decision; awaiting the required durable records.

Updated 2026-09-30: Q3 source pointers and follow-up reconciled after #536/#668. The ruling is unchanged; Q1/Q5 completion still depends on the required records owned by #534 and #538.

Updated 2026-09-30: Q5 delivered by #538/#670; replaced drifted Q5 pointers with verified links, removed the completed #538 dependency and retained #534 and the incomplete combined record criterion. Existing rulings and Q3 reconciliation are preserved.

Updated 2026-09-30: Q6 inventory/specifications and durable selection policy delivered by #539/#704. The existing rulings are unchanged; the remaining Q1 record dependency on #534 and combined Q1/Q5 criterion remain in place.

2026-10-01 triage: folded #695/#755’s delivered supported query API and the subsequently merged #698/#760 pi migration into Q7’s current implementation handoff, verified through main 2480efe13db35a75884c1ead6f73e11dfb6241cf. All eight rulings are already recorded; Q1’s durable record still awaits open #534, so the combined Q1/Q5 criterion stays unchecked. This complete tracking task has no remaining needs: prerequisite: add agent-ready while retaining blocked. No parallel implementation, SQL retirement or new architecture ruling is selected.

Updated 2026-10-01: folded the completed #692/#796 response rounding into Q6's current handoff. All existing rulings and the Q1 record dependency on open #534 remain unchanged.

Updated 2026-10-01: reconciled Q6 after #691/#803 and #694/#797 completed. All existing rulings and the Q1 record dependency on open #534 remain unchanged.

2026-10-04 correction: folded #702/#928’s verified nullable declaration delivery into Q6’s follow-up summary; #534’s remaining export prerequisite is unchanged.

2026-10-04 Q7 correction: replaced the obsolete unapproved recommendation with both dated #696 choices and verified #911/#936 record delivery. #534 remains the separate Q1 record/export prerequisite; no runtime migration, SQL retirement or immediate 1.0 freeze is claimed.

2026-10-06 triage at main 825cd044: #534 closed as completed and its Q1 record is verified on main, so the active Blocked by #534 line was retired; project sync removed blocked. The Q1/Q5 criterion is left for the closing pass to check against the records.

Activity

  1. added
    type: spikeTime-boxed investigation. The deliverable is a written decision, not code.
    area: docsThe docs/ tree and the README / AGENTS / CONTRIBUTING surfaces.
    needs: decisionBlocked on a maintainer or designer ruling, not on code.
    on Sep 25, 2026
  2. schlessera commented on Sep 28, 2026

    @schlessera
    OwnerAuthor

    Decision (maintainer, 2026-09-28), question 1: Choose C: reduce public exports before 1.0, then stabilize the deliberately public surface. Audit exported entry points and their consumers, remove accidental exposure from ordinary public entry points, and move unavoidable cross-package implementation helpers to explicitly named internal entry points with no compatibility promise. Do not freeze every currently exported name, and do not leave ordinary public exports ambiguously excluded by a distant disclaimer.

    The stable surface includes the types reachable through public signatures, not just top-level export names. Breaking that deliberately public surface after 1.0 requires a major; additions remain minor. This includes applicable behavioral guarantees, not merely type compatibility. The contract documentation must describe the same boundary that the package entry points expose.

    Reason: before external users depend on the current shape, cleanup is inexpensive and reduces long-term compatibility obligations. This chooses the API-boundary policy; the exact export inventory depends on the remaining questions in #343 and the other stability issues. It does not by itself change lockstep versioning, freeze experimental interfaces now, or schedule 1.0.

    Follow-up #534 will record the ruling in docs/decisions and implement the export/contract alignment after the remaining inventory rulings. Keep needs: decision on #343: questions 2–8 are still unresolved, so it is not agent-ready.

  3. schlessera commented on Sep 28, 2026

    @schlessera
    OwnerAuthor

    Decision (maintainer, 2026-09-28), question 2: Choose B: stabilize a small, deliberately documented backend-authoring toolkit at 1.0, while keeping implementation helpers and policy defaults internal.

    Support the permission operations backend authors are expected to reuse, including requesting approval and validating edited inputs (requestToolPermission, checkEditedApproval), together with the public types their signatures require. Audit the remaining helpers against that authoring role; do not freeze every exported helper just because first-party backends share it.

    Keep backend-specific tool lists, subprocess environment policy tables and incidental helpers out of ordinary public entry points. For public configurable policy, stabilize the format and documented behavior, not an immutable list of bundled default entries. Changes to defaults must still respect documented behavioral guarantees and be documented as user-visible changes; this is not an exemption for otherwise breaking changes.

    Reason: third-party backends should reuse permission logic instead of reproducing it, without imposing permanent compatibility obligations on first-party policy details. This follows Q1's curated-public-surface decision. Exact symbol classification and enforcement belong to #535, coordinated with #534. No interface freezes immediately; Q3–Q8 remain open, so retain needs: decision on #343.

  4. schlessera commented on Sep 28, 2026

    @schlessera
    OwnerAuthor

    Decision (maintainer, 2026-09-28), question 3: Choose A: DocumentRenderer is an internal adapter type, not a public extension interface. It describes the optional Puppeteer dependency; it is not exported through core's public entry point and has no identified second implementation requiring a provider seam.

    Make that classification explicit, preferably by moving it out of the public-seam grouping or otherwise clearly marking the internal boundary. Do not add provider injection or freeze this type at 1.0. The public CLI rendering behavior and Puppeteer package are unaffected. A future concrete second renderer can justify a separately designed extension interface.

    Agent-ready follow-up #536 records the decision and performs the small internal/documentation cleanup. Q4–Q8 remain unresolved, so #343 keeps needs: decision and is not agent-ready.

  5. schlessera commented on Sep 28, 2026

    @schlessera
    OwnerAuthor

    Decision (maintainer, 2026-09-28), question 4: Choose A: the deliberately public module-authoring API becomes stable at 1.0 and is experimental until then. The supported surface includes defineModule, the manifest and contribution shapes, command/hygiene contexts, signature-reachable types and documented load-time lifecycle, not just the helper function.

    Modules are an intended extension mechanism exercised by multiple first-party implementations. Give third-party authors a dependable foundation rather than retaining a permanent experimental exception or fragmenting this API into speculative stability tiers.

    Resolve #528's structural settings implications before freezing. Decide #59's module-MCP direction too, without requiring every proposed additive feature to ship before 1.0. Future backward-compatible optional additions may ship in minors. Known structural breaks should be addressed while the API is still experimental.

    Follow-up #537 will document and test the boundary and record this ruling. No immediate freeze or 1.0 schedule is implied. Questions 5–8 remain open, so retain needs: decision on #343.

  6. schlessera commented on Sep 28, 2026

    @schlessera
    OwnerAuthor

    Decision (maintainer, 2026-09-28): Question 5 — option A. The client/server wire protocol is part of the machine compatibility contract now, governed by the existing contract-versioning rules. Before 1.0, a breaking change requires a maintainer ruling before implementation, the breaking label, a changeset naming the break, a CONTRACT: commit and a same-commit contract update; it ships in a minor. From 1.0, breaking changes require a major. Additive changes ship in a minor.

    This is not an immediate freeze. Protocol revision negotiation and documented compatibility guarantees remain binding; incrementing a revision is not an exemption from assessing a breaking change. The protocol is not covered by the experimental extension-interface classification. Record this distinction durably and align the relevant documentation in #538, attached to #56. No wire behavior change is requested.

    Questions 6–8 remain open, so this issue retains needs: decision.

  7. schlessera commented on Sep 28, 2026

    @schlessera
    OwnerAuthor

    Decision (maintainer, 2026-09-28): Question 6 — option A. Curate an explicit supported HTTP API before 1.0. Inventory all mounted routes, deliberately identify those intended for independent clients and integrations, and explicitly classify the rest as internal. Preserve existing documented promises and account for routes used by supported SDK functionality.

    The supported route specification must cover authentication/authorization, inputs, outputs, errors and relevant behavior, not only URL names. Apply the existing machine-contract versioning rules to supported routes. This does not freeze every current route or select the final route inventory by implication. Consolidations can be proposed before 1.0; any existing contract break still requires its own ruling before implementation.

    #539, attached to #56, will produce the inventory, documentation and durable decision record. Questions 7–8 remain open, so retain needs: decision on #343.

  8. schlessera commented on Sep 28, 2026

    @schlessera
    OwnerAuthor

    Decision (maintainer, 2026-09-28): Question 7 — option B. Make the brain.db SQL schema internal before 1.0. Replace supported direct-SQL consumption with deliberately supported query APIs; keep schema versions for internal compatibility checks. This replaces the existing direct-read guarantee only once suitable replacements and consumer transitions are implemented. Until then the current SQL contract remains binding.

    Centralize SQL ownership and compatibility handling so storage layout and query results do not both become public APIs. Preserve efficient graph access: an in-process query API is an acceptable approach, and this decision does not require subprocess calls per query or select a new service architecture. Inventory and design the API before implementation, with follow-up work to move current graph and voice readers and update documentation/tests.

    The resulting supported query API follows the existing contract-versioning policy. Internal schema changes must remain compatible with shipped consumers or fail safely; internal does not mean ignoring version skew. Markdown remains authoritative and brain.db remains disposable/rebuildable.

    The transition and durable decision record will be tracked in #540, attached to #56. Question 8 remains open; retain needs: decision on #343.

  9. schlessera commented on Sep 28, 2026

    @schlessera
    OwnerAuthor

    Decision (maintainer, 2026-09-28): Question 8 — option A. Protect deliberately supported user-facing formats and keep implementation details internal. Inventory supported brain.config keys, environment variables, module settings (including #528's JSON settings) and canonical module content formats. Exclude caches and internal storage layouts from the public format contract.

    The shared policy covers meaning, validation, precedence and compatibility/migration expectations, not just names. Distinguish defaults explicitly allowed to evolve (such as curated board selections) from promised behavior; changing a documented behavioral guarantee is still a break. Module-specific documentation may define details under this one shared policy. Clean up and specify these surfaces before 1.0; supported input breaks then require a major under the existing contract-versioning rules. Existing documented promises remain binding during cleanup.

    #542 will inventory and document these surfaces and record the durable decision. It waits on #528. All eight questions now have rulings. Remove needs: decision; remaining completion waits on the required Q1/Q5 decision records in #534 and #538, so mark this issue blocked rather than agent-ready.

  10. 7 remaining items

  11. schlessera commented on Sep 30, 2026

    @schlessera
    OwnerAuthor

    Q6's scoped inventory/specification task #539 is complete through merged #704: supported HTTP contract and durable boundary policy. Concrete runtime/coverage gaps are attached to #56 as #691, #692, #693, #694 and #702. This records the existing Q6 ruling; #534 remains the completion dependency for the required Q1 record.

  12. schlessera commented on Sep 30, 2026

    @schlessera
    OwnerAuthor

    2026-09-30 triage at main aa490b4fb3e13a4fab822608827956479970d15c: folded #540/#703’s delivered Q7 design and durable record into the current brief, with #695–#701 implementation and the #696 package/context ruling still explicit. Verified the merge on main and read both documents; no SQL guarantee or architectural recommendation is adopted. Removed the stale nine-seam count against the current extension list. The required Q1 record still depends on #534, so the combined Q1/Q5 criterion remains unchecked and this issue remains blocked.

  13. added
    agent-readyContext and acceptance criteria are complete enough for an agent to take this unattended.
    on Oct 1, 2026
  14. schlessera commented on Oct 1, 2026

    @schlessera
    OwnerAuthor

    2026-10-01 triage: folded #695/#755 and #698/#760’s delivered supported query API into Q7’s current implementation handoff, verified through main 2480efe13db35a75884c1ead6f73e11dfb6241cf. All eight rulings are already recorded; Q1’s durable record still awaits open #534, so the combined Q1/Q5 criterion stays unchecked. This complete tracking task has no remaining needs: prerequisite: add agent-ready while retaining blocked. No parallel implementation, SQL retirement or new architecture ruling is selected.

  15. schlessera commented on Oct 1, 2026

    @schlessera
    OwnerAuthor

    2026-10-01 reconciliation: #692 is complete in merged #796 (a408a0f34707b5b3845bbe8b0092ca86f76d016d), verified on main with the exact CI-tested tree. Folded the delivered four-decimal response rounding into Q6 and removed #692 from its remaining implementation gaps. The original ruling, other gaps and canonical blocker #534 remain; Q1's required record and the combined Q1/Q5 criterion are still incomplete.

  16. schlessera commented on Oct 1, 2026

    @schlessera
    OwnerAuthor

    2026-10-01 — Q6 now records the delivered real HTTP coverage in #691/#803 and non-object JSON correction in #694/#797. The remaining HTTP client/type gaps are #693/#702. The recorded rulings, labels and incomplete Q1 record dependency on #534 are preserved; #691 was not a canonical blocker of this issue.

  17. schlessera commented on Oct 6, 2026

    @schlessera
    OwnerAuthor

    Unblocked: #534 is closed, so scripts/sync-project.ts is removing the blocked label.

  18. removed
    blockedWaiting on another issue or an upstream dependency. Say which in the body.
    on Oct 6, 2026
  19. added this to the 0.41.0 milestone on Oct 23, 2026
  20. schlessera commented on Oct 23, 2026

    @schlessera
    OwnerAuthor

    Closing as completed. The body's last remaining step was to check both durable records against the Q1 and Q5 rulings, and both match:

    All eight rulings and their follow-ups are filed. Implementing those rulings (#537, #701, #1345 and others) was explicitly out of scope here, and they stay open on their own. Checked on main a6b945bd9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-readyContext and acceptance criteria are complete enough for an agent to take this unattended.area: docsThe docs/ tree and the README / AGENTS / CONTRIBUTING surfaces.priority: p2Wanted, not scheduled. Pulled in when a milestone has room.type: spikeTime-boxed investigation. The deliverable is a written decision, not code.

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions