Skip to content

chore(deps): bump actions/configure-pages from 5 to 6 - #2

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/github_actions/actions/configure-pages-6
Closed

chore(deps): bump actions/configure-pages from 5 to 6#2
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/github_actions/actions/configure-pages-6

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github May 12, 2026

Copy link
Copy Markdown
Contributor

Bumps actions/configure-pages from 5 to 6.

Release notes

Sourced from actions/configure-pages's releases.

v6.0.0

Changelog

See details of all code changes since previous release.

Commits
  • 45bfe01 Merge pull request #186 from salmanmkc/node24
  • d8770c2 Update Node version from 20 to 24 in action.yml
  • cb8a1a3 upgrade to node 24
  • d560657 Merge pull request #165 from actions/Jcambass-patch-1
  • 35e0ac4 Upgrade IA Publish
  • 1dfbcbf Merge pull request #163 from actions/Jcambass-patch-1
  • 2f4f988 Add workflow file for publishing releases to immutable action package
  • 0d7570c Merge pull request #162 from actions/pin-draft-release-verssion
  • 3ea1966 pin draft release version
  • aabcbc4 Merge pull request #160 from actions/dependabot/npm_and_yarn/espree-10.1.0
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 5 to 6.
- [Release notes](https://github.com/actions/configure-pages/releases)
- [Commits](actions/configure-pages@v5...v6)

---
updated-dependencies:
- dependency-name: actions/configure-pages
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code labels May 12, 2026
@codeant-ai

codeant-ai Bot commented May 12, 2026

Copy link
Copy Markdown

Skipping PR review because a bot author is detected.

If you want to trigger CodeAnt AI, comment @codeant-ai review to trigger a manual review.

@dependabot @github

dependabot Bot commented on behalf of github May 12, 2026

Copy link
Copy Markdown
Contributor Author

Looks like actions/configure-pages is up-to-date now, so this is no longer needed.

@dependabot dependabot Bot closed this May 12, 2026
@dependabot
dependabot Bot deleted the dependabot/github_actions/actions/configure-pages-6 branch May 12, 2026 08:24
qnbs added a commit that referenced this pull request Jun 10, 2026
…i18n

Addresses every inline review comment on PR #106:

- #2 proForgeHistoryStore: reset cached dbPromise on open error so a
  failed IDB open can be retried instead of poisoning the singleton.
- #3 proForgeHistoryStore: resolve/reject on tx.oncomplete/onerror/onabort
  (not request.onsuccess) so a save only resolves once durably committed.
- #4 applyReviewEdits: anchor stale-offset edits to the occurrence nearest
  the original range and skip already-claimed positions, so duplicate
  phrases map to distinct occurrences deterministically.
- #5 baseAgent.gatherMemoryContext: feed a project-derived query
  (title/logline/genre) + ragMode into memory-bank retrieval instead of
  an undefined query; all 6 AI agents now route through it.
- #6 PipelineReviewPanel: await submitReview before announce/navigate.
- #7 useProForgeOrchestrator: always dispatch loadRunHistory (even []) so
  switching projects clears stale history.
- #1 i18n: translate ~55 proforge.review.*/stageName.* keys to es/fr/it
  (were English fallback); rebuild bundles.

Tests updated for the 4-arg gatherMemoryContext signature
(diagnostic/structural/publishing) + duplicate-phrase edit cases.

Local gates green: typecheck (--checkers 4), lint, full proForge suite.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
qnbs added a commit that referenced this pull request Jun 11, 2026
CI: suppression-debt ratchet failed (+2). CopilotMessageList used
biome-ignore-start/end pair around dangerouslySetInnerHTML; replaced
with MarkdownContent sub-component that writes via useEffect+innerHTML
so no suppression is needed (57 → 57, ratchet passes).

CodeAnt #1 (InlineAnnotationLayer): badge click only opened the panel
but left InsightSection collapsed. Added copilotInsightExpanded to
transientUiStore; badge sets it true; InsightSection consumes + resets
it via useEffect so findings are immediately visible.

CodeAnt #2 (applyLastSuggestion): always passed original='' which
forces whole-section replacement, risking data loss for partial
snippets. Added 70% length gate — only full-chapter-rewrite blocks
(codeBlock.length ≥ 70% of section) are applied; shorter blocks
return error status without touching content.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
qnbs added a commit that referenced this pull request Jun 11, 2026
…co bridge, routing observability

* feat(copilot): Phase 2 — markdown rendering, sidebar mode, Apply-to-chapter, InlineAnnotationLayer

- CopilotMessageList: micro-markdown renderer (~80 lines, zero deps) + DOMPurify-sanitized
  dangerouslySetInnerHTML for assistant messages; user messages remain plain text.
  "Apply to chapter" button on last assistant message when it contains a fenced code block
  and an active manuscript section is available.

- CopilotPanel: sidebar/dialog mode toggle persisted in localStorage ('copilot.mode').
  Sidebar docks to the inline-end at full height; dialog keeps the existing floating
  behaviour. Toggle hidden on mobile (< md breakpoint). Apply feedback strip (success/error)
  shown below the composer.

- actionApplier.ts (new): thin wrapper around applyReviewEditsToSection for copilot-
  initiated edits. applyTextEdit() does whole-section replacement when original is empty
  (AI full-rewrite path) or offset-safe partial replacement otherwise. extractCodeBlock()
  pulls the first fenced block from a markdown string.

- InlineAnnotationLayer.tsx (new): absolute-positioned badge inside the manuscript editor
  that shows a count of heuristic findings matching the current section title. Clicking
  opens the Copilot panel. Gated behind enableGlobalCopilot.

- transientUiStore: added activeSectionId + setter; useManuscriptView writes it on every
  section change so copilot apply-flow and InlineAnnotationLayer can read it without
  prop-drilling.

- useGlobalCopilot: applyLastSuggestion() dispatches updateManuscriptSection (undo-able),
  applyStatus drives button state. Added activeSectionId read from transient store.

- i18n: 7 new keys across all 11 locales: sidebarMode, dialogMode, apply,
  applyingChange, changeApplied, changeApplyFailed, annotationCount (2530 keys total).

- Tests: actionApplier.test.ts (9 tests); transientUiStore mock extended for Phase 2 keys.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(copilot): suppression ratchet + CodeAnt findings on PR #111

CI: suppression-debt ratchet failed (+2). CopilotMessageList used
biome-ignore-start/end pair around dangerouslySetInnerHTML; replaced
with MarkdownContent sub-component that writes via useEffect+innerHTML
so no suppression is needed (57 → 57, ratchet passes).

CodeAnt #1 (InlineAnnotationLayer): badge click only opened the panel
but left InsightSection collapsed. Added copilotInsightExpanded to
transientUiStore; badge sets it true; InsightSection consumes + resets
it via useEffect so findings are immediately visible.

CodeAnt #2 (applyLastSuggestion): always passed original='' which
forces whole-section replacement, risking data loss for partial
snippets. Added 70% length gate — only full-chapter-rewrite blocks
(codeBlock.length ≥ 70% of section) are applied; shorter blocks
return error status without touching content.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(test): stub InlineAnnotationLayer in ManuscriptEditor unit tests

InlineAnnotationLayer was added to ManuscriptEditor in Phase 2 but
imports useAppDispatch + useTransientUiStore, neither of which was
mocked in the ManuscriptEditor test suite. Added useAppDispatch to
the app/hooks mock and stubbed InlineAnnotationLayer as a no-op so
ManuscriptEditor tests remain focused on the editor itself.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(copilot): Phase 3 — ProForge chip, E2E tests, docs, AUDIT/CHANGELOG

Phase 3 of Ultimate Copilot AI v2:

- ProForge PipelineReviewPanel: "Ask Copilot" chip on every ReviewItemCard
  (gated by enableGlobalCopilot). Clicking pre-fills the Copilot composer
  with the review item's severity + description and opens the panel — no
  prop-drilling needed (copilotDraftMessage in transientUiStore consumed
  once by CopilotComposer via useEffect).
- E2E: 2 new tests in copilot-flags.spec.ts — heuristics-only toggle
  (aria-pressed state) + sidebar mode toggle (label flip on desktop).
- docs/COPILOT.md: full user-facing feature guide.
- docs/HEURISTIC-RULES.md: per-rule reference (8 rules, how to satisfy each).
- AUDIT.md + CHANGELOG.md: updated to v1.21.2 with Phase 2+3 summary.
- i18n: copilot.askCopilot + copilot.askAboutReviewItem × 11 locales (2532 keys).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ai,palette): AI execution mode management + expanded command palette (Phase 4)

Adapts CannaGuide-2025 AI mode routing into StoryCraft — hybrid/cloud/local/eco
modes with full policy gate, Settings UI card picker, and 20+ new palette commands
for themes, appearance presets, accessibility, editor modes, and AI modes.

Also fixes CI quality-gate regression: PipelineReviewPanel tests failed because
the Phase 3 component gained direct useAppDispatch/useAppSelector calls (copilot
flag) without a corresponding mock in the test — added app/hooks mock to resolve
all 27 failures without needing a Redux Provider.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): fix CommandPalette + commandTypes test regressions from palette expansion

CommandPalette mock was missing advancedEditor/appearancePreset/aiMode settings
fields added in Phase 4; commandTypes category count updated 8→10 for the new
appearance and accessibility categories.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(e2e): fix copilot E2E — role=switch/aria-checked + locale string alignment

HeuristicsModeToggle renders as <button role="switch" aria-checked> (ARIA switch
pattern); E2E test was querying getByRole('button') + aria-pressed — corrected to
getByRole('switch') + aria-checked.

Sidebar mode locale strings "Dock as sidebar"/"Float as dialog" didn't match test
regexes /Dock sidebar/i and /Float panel/i; updated to "Dock sidebar"/"Float panel"
across all 11 locales + rebuilt bundles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ai-mode): seed aiModeService from persisted settings on cold start

Cold-start bug G1: setupStore(preloadedState) hydrated Redux but
aiModeService singleton stayed at 'hybrid' default until first setting
change. Now seeded immediately from persisted Redux state after store
init, and OpenRouter config is also applied from persisted settings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ai-mode): positive routing + OpenRouter integration (G2, G10)

- shouldRouteLocally() now called in generateText() and inferenceGateway
  to positively override provider to webllm when mode mandates local
- Hybrid mode is cloud-first: shouldRouteLocally() returns isOffline() only
- getLocalFallbackModel(): eco → SmolLM2-135M, others → Llama-3.2-1B
- getLocalModelsReady() exported so health panels can read readiness signal
- OpenRouter provider: circuit breaker (4 × 429 → 5min pause), exponential
  backoff with Retry-After header, RPM tracking, isOpenRouterFreeModel()
- shouldUseOpenRouter(), getOpenRouterModel(), getOpenRouterFallbackProvider()
  wired into routing chain in aiProviderService and inferenceGateway
- OpenRouterSettings type + settingsSlice reducer + idbProjectStore backfill
- All new symbols exported from services/ai/index.ts entry point

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ai-mode): notifyLocalModelsReady wired from localAiFacade on model load (G4)

WebLLM inference success now calls notifyLocalModelsReady(true) so
hybrid mode has accurate readiness signal for faster offline recovery.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ai-mode): phases 2-7 — eco bridge, observability, indicator, i18n, tests

Phase 2: notifyLocalModelsReady() wired from localAiFacade after successful
WebLLM inference — hybrid mode now has accurate readiness signal (G4).

Phase 3: ecoModeService.setAiModeEco() bridged from listenerMiddleware aiMode
listener; battery auto-eco back-syncs to Redux via appStoreRef; GpuMetricsPanel
eco toggle routes through Redux dispatch instead of bypassing state (G3, G7).

Phase 4: baseAgent.buildAiOpts() consults shouldRouteLocally() + isEcoMode() —
ProForge pipeline no longer fires cloud calls regardless of aiMode (G5).

Phase 5: services/ai/routingLogger.ts — logRoutingDecision() called at every
routing branch in aiProviderService and inferenceGateway (G8).

Phase 6: AiModeIndicator component in Copilot panel header — shows current
mode chip + OpenRouter circuit/RPM status; 2583 keys × 11 locales (G9).

Phase 7: 49 unit tests across aiModeService, routingLogger, ecoModeBridge,
openrouterProvider — all passing; lint + typecheck clean.

TODO.md updated with all remaining follow-up items (OpenRouter Settings UI,
command palette integration, API key retrieval wiring, test coverage gaps).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(settings): OpenRouter settings panel + baseAgent routing fix (P1/P3)

P1 — OpenRouterSection.tsx: enable toggle (Redux), API key input (stored via
storageService AES-256-GCM), free-model selector + custom model input,
circuit-breaker status badge + reset button, RPM indicator (5s poll).
Wired into SettingsView NAV_GROUPS aiModels group + navCategories + renderContent.
12 new i18n keys × 11 locales (2594 keys total).

P3 — baseAgent routing fix: routingOverrideActive flag ensures getLocalFallbackModel()
is used as model when shouldRouteLocally() overrides provider to webllm. Previously
model stayed 'gemini-2.5-flash' (modelMap['webllm'] = undefined → fallback).
4 new tests cover routing: webllm override, no-override, local provider passthrough,
eco model. baseAgent.test.ts now mocks aiModeService.

P4 — confirmed already wired: aiProviderService case 'openrouter' already calls
storageService.getApiKey('openrouter') — no change needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(security): upgrade joi transitive dep from 17.13.3 to 18.2.1

GHSA-q7cg-457f-vx79 (Medium, CVSS 5.3) — joi@17.13.3 pulled transitively
by @storybook/test-runner→jest-process-manager→wait-on@7.2.0. Patched
lockfile to resolve wait-on@7.2.0 against the already-present joi@18.2.1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): GpuMetricsPanel — add useAppDispatch to mock, fix dispatch assertion

Mock for app/hooks was missing useAppDispatch, causing all 14 tests to fail
with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH. Eco-toggle test updated to assert
dispatch() call (component routes through Redux, not ecoModeService directly).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(todo): add dependency-hygiene backlog items

Document follow-up tasks from joi CVE session: .npmrc hardening,
override housekeeping, Renovate grouping, audit threshold bump,
and AUDIT.md known-overrides table entry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
qnbs added a commit that referenced this pull request Aug 1, 2026
- Cargo.lock: sync tauri-plugin-notification dependency via
  `cargo metadata` (minimal-diff, no unrelated version bumps).
- useExportView: only send the 'export complete' desktop notification
  when the export actually succeeded; PDF/DOCX/EPUB now report success/
  failure instead of always resolving. Adds coverage for the failure
  paths.
- useTauriUpdater: fix test suite that lacked a Redux <Provider> wrapper
  (was passing accidentally, not exercising the real selector).
- settingsSlice: merge (not replace) desktop settings on setSettings so
  a legacy/imported settings envelope that predates a new
  DesktopSettings field (e.g. desktopNotifications) doesn't clobber it
  back to undefined.
- listenerMiddleware: replace hardcoded English ProForge notification
  strings with i18n via a new middleware-safe static translator
  (services/i18n/staticTranslate.ts), since listener middleware runs
  outside React and can't call useTranslation(). New
  desktop.notify.proforgeStageReady{Title,Body} keys across all 19
  locales (core 4 hand-translated, Beta/RTL backfilled with EN
  fallback via check-i18n-keys.mjs --fix).

Refs: PR #306 review threads (Copilot reviewer findings #2-#7).
qnbs added a commit that referenced this pull request Sep 5, 2026
…o-loss precision

Six corrections from review, each verified against live source before
fixing:

1. Version-classification overlap bug: the original state machine used
   a hardcoded "schemaVersion == 1" example inside SUPPORTED_OLDER,
   which is ambiguous with CURRENT at the very first release where
   version 1 is also current. Rewrote all classifications as strict
   comparisons against CURRENT_PROJECT_SCHEMA_VERSION, and added the
   missing UNSUPPORTED_OLDER/MIGRATION_GAP state (an older version with
   no registered migration path) as a genuinely distinct state from
   FUTURE, mirroring migrate.rs's existing MigrationError::NoMigrationFrom.

2. Field inventory was too narrow -- the most significant gap. Verified
   against live source: features/project/projectState.ts's ProjectData
   (the actual persisted/Redux shape) has ~20 fields, while types.ts's
   StoryProject interface (what coreEnvelope.ts operates on) has only
   11, and coreEnvelope.ts's buildCoreProjectEnvelope further narrows
   to 6 fields for the shadow envelope. Three narrowing steps exist,
   not the one the original draft described. Added §1.5 documenting
   this, §2.1.1 explicitly deciding that schemaVersion versions the
   full ProjectData surface (not StoryProject or the shadow-envelope
   projection), and a complete field-by-field inventory table covering
   every ProjectData field, not only the five schema.rs's own doc
   comment names.

3. The raw-carrier + typed-projection mechanism (§3.1) had no defined
   write-back invariant for editing a known field without destroying
   opaque sibling data. Added §3.2: known-field edits overlay onto the
   existing raw payload rather than re-serializing the typed projection
   as the whole document, with a source-generation revalidation before
   commit that fails closed on a stale merge target -- connects forward
   to future multi-writer/generation-authority work without
   implementing it here.

4. "Verbatim" preservation language contradicted the document's own
   semantic-equality (not byte-identical) no-loss definition. Replaced
   with precise semantic-preservation wording that explicitly allows
   whitespace/key-order/escape differences.

5. CORE-MIGRATION-LEDGER.md's row 9 update oversimplified the decision
   as a single "PRESERVE_OPAQUE unknown-field policy" when the actual
   proposal stages four distinct policies by field class. Corrected the
   wording.

6. Extended §9's maintainer decision record from 8 to 10 rows to cover
   the versioned-object decision (#2) and the write-back invariant
   (#9) as their own explicit, confirmable decisions rather than
   leaving them implicit under other rows.

No code change. No authority switch. Still awaiting maintainer sign-off
per §9 before this is treated as admitted.
qnbs added a commit that referenced this pull request Sep 5, 2026
…olicy (#553) (#617)

* docs(native): propose project/core schema-version and unknown-field policy

Issue #553 (CORE-MIGRATION-LEDGER.md row 9's Wave 2 prerequisite,
blocking R-15/#445 implementation) requires two decisions that no
existing roadmap/ADR settles: where persisted project schema-version
authority lives, and an explicit unknown-field policy that can never
silently drop persisted user data.

Adds docs/native/PROJECT-CORE-COMPATIBILITY-CONTRACT.md as a proposal,
not yet admitted:

- Persisted schemaVersion belongs to the project document itself,
  distinct from app/IndexedDB/contract/R-15 versions already tracked
  elsewhere in this codebase.
- First production version starts fresh at PROJECT_SCHEMA_V1 -- the
  existing Rust migrate.rs V1ToV2 proof and its revision_note field are
  explicitly harness-only (schema.rs's own doc comment says so) and are
  not canonicalized as real project history.
- Absent version classifies as LEGACY_UNVERSIONED, a distinct sentinel
  from PROJECT_SCHEMA_V1, never silently treated as current -- avoiding
  the exact synthesized-version risk issue #553 warns about.
- Future version fails closed (no write authority, no auto-migration,
  no auto-downgrade), mirroring the fail-closed philosophy migrate.rs
  already implements for its harness proof.
- Unknown-field policy is staged by field class rather than one global
  choice: not-yet-modeled persisted data (outline, binderNodes,
  compileProfile, projectGoals, writingHistory -- schema.rs's own
  StoryProject doc comment names these as out of scope today) gets
  OUT_OF_SCOPE_BUT_MUST_NOT_BE_DROPPED; additive fields on an
  already-Core-owned object get PRESERVE_OPAQUE; unknown values for
  closed semantic discriminants get REJECT_UNKNOWN; fully-owned fields
  get MODEL_AND_VALIDATE.
- Mechanism: a raw canonical payload as the lossless carrier, with a
  typed Core projection validating only currently-owned fields --
  evaluated per-struct rather than a blanket serde flatten/extra bucket
  across the whole object graph.
- Precise no-loss definition (semantic JSON equality, not
  byte-identical), a version-classification state machine, and
  authority-switch admission gates, none of which are satisfied yet.

CORE-MIGRATION-LEDGER.md row 9 updated to reference this proposal.

No code change. No authority switch. A maintainer decision record
(section 9) lists each decision for explicit confirmation before this
is treated as admitted; implementation is a separate, later PR.

* docs(native): fix version-state overlap, field-inventory scope, and no-loss precision

Six corrections from review, each verified against live source before
fixing:

1. Version-classification overlap bug: the original state machine used
   a hardcoded "schemaVersion == 1" example inside SUPPORTED_OLDER,
   which is ambiguous with CURRENT at the very first release where
   version 1 is also current. Rewrote all classifications as strict
   comparisons against CURRENT_PROJECT_SCHEMA_VERSION, and added the
   missing UNSUPPORTED_OLDER/MIGRATION_GAP state (an older version with
   no registered migration path) as a genuinely distinct state from
   FUTURE, mirroring migrate.rs's existing MigrationError::NoMigrationFrom.

2. Field inventory was too narrow -- the most significant gap. Verified
   against live source: features/project/projectState.ts's ProjectData
   (the actual persisted/Redux shape) has ~20 fields, while types.ts's
   StoryProject interface (what coreEnvelope.ts operates on) has only
   11, and coreEnvelope.ts's buildCoreProjectEnvelope further narrows
   to 6 fields for the shadow envelope. Three narrowing steps exist,
   not the one the original draft described. Added §1.5 documenting
   this, §2.1.1 explicitly deciding that schemaVersion versions the
   full ProjectData surface (not StoryProject or the shadow-envelope
   projection), and a complete field-by-field inventory table covering
   every ProjectData field, not only the five schema.rs's own doc
   comment names.

3. The raw-carrier + typed-projection mechanism (§3.1) had no defined
   write-back invariant for editing a known field without destroying
   opaque sibling data. Added §3.2: known-field edits overlay onto the
   existing raw payload rather than re-serializing the typed projection
   as the whole document, with a source-generation revalidation before
   commit that fails closed on a stale merge target -- connects forward
   to future multi-writer/generation-authority work without
   implementing it here.

4. "Verbatim" preservation language contradicted the document's own
   semantic-equality (not byte-identical) no-loss definition. Replaced
   with precise semantic-preservation wording that explicitly allows
   whitespace/key-order/escape differences.

5. CORE-MIGRATION-LEDGER.md's row 9 update oversimplified the decision
   as a single "PRESERVE_OPAQUE unknown-field policy" when the actual
   proposal stages four distinct policies by field class. Corrected the
   wording.

6. Extended §9's maintainer decision record from 8 to 10 rows to cover
   the versioned-object decision (#2) and the write-back invariant
   (#9) as their own explicit, confirmable decisions rather than
   leaving them implicit under other rows.

No code change. No authority switch. Still awaiting maintainer sign-off
per §9 before this is treated as admitted.

* docs(native): explicit legacy migration step, downgrade barrier, MD018 fix

Five corrections from a further review pass:

1. LEGACY_UNVERSIONED was described as dispatching into
   PROJECT_SCHEMA_V1's migration-registry entry for convenience, which
   -- since v1 is also the initial current version -- implied no
   explicit step ever actually executes, silently relabeling a legacy
   record as current with no stamp written and no verification
   performed. Replaced with an explicit, distinct, registered
   LEGACY_TO_V1 migration step (recognize legacy shape -> verify
   conformance to the v1 field inventory -> write schemaVersion: 1 for
   the first time -> no-loss verify -> durable commit).

2. Added a new required invariant, pre-contract downgrade safety
   (Sec 2.7): once a project is migrated to the schema-aware canonical
   form, a still-installed pre-contract build mutating its own
   untouched legacy-shaped copy must never have that mutation silently
   supersede the already-migrated record. The exact storage mechanism
   is left to the implementation PR (matching how Sec 2.1 already
   leaves the envelope representation unspecified), but the invariant
   itself is fixed here since it's a real product-format decision, not
   an implementation detail. Added as authority-switch gate 8 and
   Sec 9 decision row 12.

3. Fixed a markdown MD018 violation: a paragraph line-wrapped such
   that "#553" started a bare physical line, which markdownlint-cli2
   parses as an ambiguous ATX heading attempt. Wrapped issue/PR number
   references in backticks throughout so no line can start with a bare
   #NNN regardless of future rewrapping.

4. Resolved the Sec 5 gate-status self-contradiction CodeRabbit flagged
   (claiming "none are satisfied" while gate 7 said "already satisfied
   structurally"): reworded to distinguish "has structural evidence
   today" from "verified sufficient for an actual switch" -- only the
   latter closes any gate.

5. Made TS/Rust accept/reject parity (gate 4) a permanent, ongoing
   requirement rather than one scoped to "any transition window" --
   the React/PWA product and any native Core/Qt consumer are both
   permanent, coexisting implementations of the same format, not a
   temporary migration pair.

Also added a full fixture-class checklist (Sec 6.2) so gate 3's
"every fixture class" is no longer a dangling reference -- the
previous commit introduced this reference before the list existed to
back it.

No code change. No authority switch. Still awaiting maintainer
sign-off per Sec 9 before this is treated as admitted.

* docs(native): fix malformed-recovery claim, race-close write-back, raw version parse

Four corrections from a further review pass, each verified before
fixing:

1. The MALFORMED classification claimed "existing preserve-first
   recovery UX, unchanged" -- verified false against live source:
   index.tsx's hydration path calls normalizePersistedProjectForStore,
   and on a falsy result it deletes the project key from
   preloadedState entirely, letting the app boot a blank project whose
   autosave can subsequently overwrite the original malformed record.
   This is destructive, not preserve-first. Corrected the claim and
   added it as authority-switch gate 9 / decision row 13: the web/IDB
   path must be brought to the same non-editable blocking recovery
   already required for FUTURE/MIGRATION_GAP, not assumed already
   correct.

2. Version classification implicitly assumed a full typed-schema parse
   happens before classification, but a FUTURE document making a
   breaking schema change (a plausible way for a real future version
   to differ) would fail that parse before its version is ever
   compared, misclassifying FUTURE as MALFORMED and denying it the
   correct newer-build recovery path. Added an explicit requirement:
   classification reads schemaVersion via a minimal raw/header parse
   first, full typed parsing only afterward.

3. The write-back merge invariant (Sec 3.2) verified only that unowned
   (opaque) paths survived unchanged -- an overlay bug that omitted an
   edit or wrote it to the wrong path would still pass that check and
   silently commit the wrong value. Added a second, owned-path
   verification: re-project the merged payload and confirm every owned
   path equals the intended edit before committing.

4. The same invariant's generation revalidation and the durable commit
   were described as two sequential steps, leaving a window for
   another writer to commit between them -- exactly the race the check
   exists to prevent. Specified that validation and commit must be one
   atomic, fenced operation (compare-and-swap or an exclusive lease
   spanning both), not a check-then-act pair.

Extended Sec 6.2's fixture list and Sec 9's decision record (rows
13-16) to cover all four. No code change. No authority switch. Still
awaiting maintainer sign-off per Sec 9 before this is treated as
admitted.

* docs(native): final bounded amendment - ingress admission, merge-by-ID, bump policy

Closes the contract boundary per explicit maintainer scoping -- four
contract-level invariants only, no further open-ended review cascade,
no runtime implementation.

1. Universal ingress admission (Sec 2.8, contract invariant, admitted
   now): classification and schema admission must run on every ingress
   capable of producing editable project state, not only the primary
   load path -- naming stored-project load, filesystem load, IDB load,
   file/backup import, snapshot restore, recovery restore, and future
   native/Qt open as examples. Concrete per-path code changes are
   IMPLEMENTATION_REQUIRED, not designed here.

2. Identity-bearing collection merge (Sec 3.2, contract invariant,
   admitted now): characters, worlds, and equivalents merge by stable
   entity ID during the write-back overlay, never by array index or
   object-enumeration position; opaque sibling fields stay attached to
   the correct entity identity. Concrete merge implementation is
   IMPLEMENTATION_REQUIRED.

3. Schema version-bump policy (Sec 2.9, design decision, admitted
   now): required-field additions, removals/renames, type changes,
   incompatible semantic/invariant changes, non-additive
   closed-discriminant changes, and identity/order semantic changes
   all require a bump; a purely additive optional field routed through
   the staged unknown-field policy does not. This classification is a
   permanent release invariant, evaluated for every future format
   change.

4. Fixture-gate scoping correction (Sec 5 gate 3, Sec 6.2): split
   fixtures into admitted/migrated (semantic no-loss round-trip
   applies) and refused -- FUTURE, MIGRATION_GAP, MALFORMED (source
   preserved unchanged, zero durable writes, zero editable-state
   admission; never a round-trip proof, since nothing about a refused
   input is meant to be admitted or transformed).

Extended Sec 9 with rows 17-19 for the three new decisions, plus an
explicit IMPLEMENTATION_REQUIRED status block distinguishing every
concrete mechanic this document names from what it actually
implements (nothing -- this remains a proposal).

No code change. No authority switch. Awaiting maintainer sign-off per
Sec 9. This closes the proposal-development loop; further findings
belong to the implementation PR's own review, not another round here.

* docs(native): close 6 post-signoff review gaps in Core compatibility contract

Six chatgpt-codex-connector findings landed on the already-signed-off head,
each verified against live source or the binding native roadmap before being
addressed: a cross-process-unsafe example in the write-back fence mechanism;
TS/Rust parity scoped to accept/reject only, missing migration-output
equality; the no-loss definition not accounting for the already-admitted
field-removal/rename bump case; the Group B refusal blanket not accounting
for the concurrent-write fixture starting from an already-admitted project;
no egress counterpart to universal ingress admission (verified against
useSettingsView.ts, BackupQuickActionsCard.tsx, libraryBackupService.ts, all
of which serialize a narrowed typed projection rather than the canonical raw
payload); and migration backup retention scoped only to "until commit," short
of ROADMAP-QT-GPUI-DESKTOP.md section 20's "backup before destructive
migration" rule.

None of these required a new product/security/legal decision or contradicted
any of the 19 maintainer-approved decision rows; each closes a loophole in an
already-admitted invariant and is recorded inline at its section.

* docs(native): admit Project/Core compatibility contract (#553)

Maintainer sign-off covers the contract/design level, including section 9's
19 decision rows and the post-signoff refinements recorded above this
commit. Flips the status line to ADMITTED = YES, marks all 19 rows
confirmed, and updates CORE-MIGRATION-LEDGER.md row 9 to reflect admission.

IMPLEMENTATION_STARTED remains NO — no runtime code changes in this commit.
Implementation proceeds in separate, subsequent PRs per issue #553's slices.

* docs(native): close 5 second-wave review gaps on the admission commit

Five findings landed on the admission commit itself (CodeRabbit x3,
chatgpt-codex-connector x2), each verified before being addressed: stale
proposal-stage confirm/amend/reject wording left in section 9's intro after
admission; the field inventory not stating that schemaVersion itself is
deliberately excluded from that table; the version classification not
defining accepted-value grammar for a present-but-invalid schemaVersion;
a verified gap where the filesystem backend (projectFsStore.ts,
legacyProjectIdentity.ts) persists two backend-specific fields absent from
ProjectData's declared type; and an explicit scope boundary against
ADR-0008's accepted-but-not-yet-flipped local-first Y.Doc authority model,
which this document does not extend to.

None required a new product/security/legal decision or contradicted any of
the 19 maintainer-approved decision rows.

* docs(native): close 6 third-wave review gaps; close the review-cascade loop

Six findings landed on the second-wave commit, each verified before being
addressed: the filesystem-metadata inventory row implied ordinary opaque
preservation across portable boundaries for local machine-trust data that
actually drives asset routing/quarantine decisions (corrected to require
stripping/re-derivation at portable boundaries); the additive-closed-enum
bump exemption contradicted REJECT_UNKNOWN's fail-closed intent (removed);
MODEL_AND_VALIDATE's "already validated" claim did not hold for a verified
field (wordCount) with a real TS/Rust domain mismatch (added a
never-invalidate-existing-data requirement); the no-loss definition did not
address JS/Rust large-integer precision divergence (added a lossless-numeric
requirement); the migration rename exemption did not require verifying a
renamed value landed at its destination (added); and the egress requirement
omitted snapshot creation as a distinct fourth call site (added).

None required a new product/security/legal decision or contradicted any of
the 19 maintainer-approved decision rows. This document is now explicitly
closed to further design-cascade rounds per its own new closing note: any
further finding is dispositioned in its review thread, not absorbed as
another revision.

* docs(native): fix a real self-contradiction with decision row 4, plus 3 gaps

The wave-two accepted-value-grammar text wrongly classified an absent
schemaVersion as MALFORMED, directly contradicting decision row 4
(LEGACY_UNVERSIONED, never MALFORMED, for an absent version) - a genuine bug
in this document's own prior text, not a refinement. Fixed, along with
making duplicate-schemaVersion-key rejection deterministic rather than
parser-dependent (was breaking permanent TS/Rust parity).

Two further real gaps, fixed alongside it: the write-back overlay invariant
read as scoped to a future Core writer only, when TypeScript is the actual
permanent writer it must also bind; and ordinary entity insertion/deletion
had no exception from "no invented/missing fields," making normal
add/delete character actions impossible to satisfy alongside the write-back
invariant.

This document is now explicitly closed to further design-cascade rounds -
a further finding is fixed only if it is a genuine self-contradiction with
an admitted row, otherwise dispositioned in its review thread without
another revision.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants