docs: align O2 chapter conversion and Case 2 access with owner rulings
This commit is contained in:
1 parent
0b923a2759
commit
ee5f7b9ef8
4 files changed
+757
-800
No files matched your search
@@ -5366,3 +5366,9 @@ Gander: after Duckworth-0100 design approval with C1-C5, prepared the two host-s
|
|||||||
2026-10-22T23:23:42Z | Rocko, W4 #1799 | Before, D24-D26 had no separate exact DOCX citation/access contract. After, 15e91538f proposed a versioned schema, parser/story/view/refusal rules, live authorization/sharing and generic/git/session bypass closure, compatibility gates and 22 acceptance rows. Two JSON examples parse, diff check clean; no code or implementation acceptance. Megavolt review pending.
|
2026-10-22T23:23:42Z | Rocko, W4 #1799 | Before, D24-D26 had no separate exact DOCX citation/access contract. After, 15e91538f proposed a versioned schema, parser/story/view/refusal rules, live authorization/sharing and generic/git/session bypass closure, compatibility gates and 22 acceptance rows. Two JSON examples parse, diff check clean; no code or implementation acceptance. Megavolt review pending.
|
||||||
|
|
||||||
2026-10-22T23:55:11Z | Sage, W4 #1799 docs landing | Megavolt reviewed four rounds (CHANGES 15e91538f, 019a0ea5b, 54246cb32; APPROVE 994c3f7fb, #1799 c30868/c30870/c30876/c30884). Landed here as cherry-picks: docs/plans/2026-10-22_q195-docx-citations.md blob 2af460ab7 and docs/reviews/2026-10-22_q195-docx-citations.md blob bedde1716, both new files. 32 acceptance rows go to W4b; R4-N1 (re-migration after a pre-W4b restore keeps the rotated fence and needs owner confirmation) goes into W4b's brief and A32. W4 is design-approved only: its gate still needs Sage's W4b implementation brief, which waits for S0 (#1798) PASS. Q36 open, adoption closed. Docs only, no test reads these files.
|
2026-10-22T23:55:11Z | Sage, W4 #1799 docs landing | Megavolt reviewed four rounds (CHANGES 15e91538f, 019a0ea5b, 54246cb32; APPROVE 994c3f7fb, #1799 c30868/c30870/c30876/c30884). Landed here as cherry-picks: docs/plans/2026-10-22_q195-docx-citations.md blob 2af460ab7 and docs/reviews/2026-10-22_q195-docx-citations.md blob bedde1716, both new files. 32 acceptance rows go to W4b; R4-N1 (re-migration after a pre-W4b restore keeps the rotated fence and needs owner confirmation) goes into W4b's brief and A32. W4 is design-approved only: its gate still needs Sage's W4b implementation brief, which waits for S0 (#1798) PASS. Q36 open, adoption closed. Docs only, no test reads these files.
|
||||||
|
|
||||||
|
2026-10-23T00:52:58Z | Gyro Q235-Q237 policy rewrite started, Vikunja 571, mos-1366/1367 | Before: approved O2 e36bce352 keeps Markdown originals at their paths and Q36 notices open; landed W4 2af460ab7 has the same boundary. Imported that byte-identical W4 baseline as 1ac76a417, from refactor 062646487, to make the policy-only revision diff explicit. Prepared P1-P6/B1-B4: human one-way per-story import, human-set source-repo archive, DOCX current reader, scoped format map/archived non-canon reads, W7 conversion publication after W4b/approved PRD/10-27 and Jason first-real-book go. Q234 exact CSP, mos-1363 and S0 M1-M14 retained. W4 locator/extractor, shares and restore-fence blocks compare byte-identical to the approved baseline. Scope/source review ongoing; Mos impact map must be folded before Fenton handoff. No build/browser/worker run, code, queue, private-book or live action.
|
||||||
|
|
||||||
|
2026-10-23T01:37:07Z | Gyro Vikunja571 final impact-map / mos-1372/1375 fold | Prepared parent/W4 rewrite against brain-redux d183246 impact map at stack 062646487. P1-P6/B1-B4 and engineering Q1-Q16 are mapped to eleven briefs. D9 replaces the earlier private O2-only context/per-document/share model: normal Case 2 access in any authorized thread/room, supporting writes intact, changed policy awaits PRD 1.17 approval. New DOCX story creation has the same opening gate as human per-story import. Host-only push to human-set off-host remote replaces the no-remote ban; remoteURL defaults unset and same-host bare is disallowed. W7 gates on Hermes #423 step5, W4b, PRD approval, post-10-27 and first-real-book go; owns conversion events COUNTED/--events/pre-conversion restore reconciliation, manifest order/next_chapter, creative role cite wording, archive/old-path edits and format/link/citation routing. Store+off-host acknowledgment precedes archive commit/push, then catalogue publication; post-push failures remain resumable pending with pinned source. Current checks pass: complete brief fields, policy/map coverage, exact Q234 CSP, locator/projection mechanics byte-equivalent except explicit authority wording, A01-A35 IDs, immutable map pin, four-doc scope and append-only logs. W4 authority/remote/recovery sections reopened for Fenton; older APPROVE not reused. No product/build/browser/worker/private-book/queue/live action. Earlier entry describing preserved shares/fence applies only to the pre-D9 intermediate draft; D9 now withdraws those unimplemented structures.
|
||||||
|
|
||||||
|
2026-10-23T01:37:55Z | Gyro 571 push guard | identity gyro/purpose push: exit 0 documented degraded-pass CANNOT_ASSERT credential-unresolvable, scratch audit gyro-q195-ci-queue-audit.jsonl; no credential fallback or CI-green claim.
|
||||||
@@ -1559,3 +1559,5 @@ are never rewritten or removed; corrections are new entries.
|
|||||||
2026-10-22 23:48Z | rocko | Q195 O2 W4 #1799 design approved | W4 #1799 design approved at 994c3f7fb (Megavolt 67f82a12d), 32 acceptance rows assigned to W4b; static docs/public-fixture inspection only, no implementation PASS. Q36 remains OPEN and adoption CLOSED. Sage's accepted implementation brief remains required. Row219 remains separately held pending your next direction.
|
2026-10-22 23:48Z | rocko | Q195 O2 W4 #1799 design approved | W4 #1799 design approved at 994c3f7fb (Megavolt 67f82a12d), 32 acceptance rows assigned to W4b; static docs/public-fixture inspection only, no implementation PASS. Q36 remains OPEN and adoption CLOSED. Sage's accepted implementation brief remains required. Row219 remains separately held pending your next direction.
|
||||||
2026-10-22T23:55:11Z | Sage (Opus 5.5, 1ef1e4f8) | Row 203 landing, O2 design landing, W4 docs landing | 203 LANDED a4da4e6df (Webby c30877, rev 3366), #1701 closed c30882, P19 269 c835. O2 design (mos-1360/1361) pushed 25c09f19f, blob 322ec50f matches fenton-0008. W4 #1799 APPROVE round 4 posted c30884; design 2af460ab7 and review bedde1716 land here. Queue revs 3360-3368 in 4ca270307. 270+271 r4 rebased by Gizmoduck onto 25c09f19f for new Duckworth rounds.
|
2026-10-22T23:55:11Z | Sage (Opus 5.5, 1ef1e4f8) | Row 203 landing, O2 design landing, W4 docs landing | 203 LANDED a4da4e6df (Webby c30877, rev 3366), #1701 closed c30882, P19 269 c835. O2 design (mos-1360/1361) pushed 25c09f19f, blob 322ec50f matches fenton-0008. W4 #1799 APPROVE round 4 posted c30884; design 2af460ab7 and review bedde1716 land here. Queue revs 3360-3368 in 4ca270307. 270+271 r4 rebased by Gizmoduck onto 25c09f19f for new Duckworth rounds.
|
||||||
2026-10-23T00:05:06Z | Filbert (Opus 5.5, sage-3059/3064) | Q195 O2 S0 (#1798) static review of Fenton's fenton/q195-s0 85ae2be77 (security + CSP reports, receipts in s0-20261022) | CONCUR CONDITIONAL PASS, c30914; A1 M1 needs WOFF2 and summed-size tests, A2 F2/D7 misstate the ctrl+click gate, M2 retargets to DOCX save; N1-N4 non-blocking; D8 hash question stays with Mos; no queue row (mos-1361), no slot, harness not rerun
|
2026-10-23T00:05:06Z | Filbert (Opus 5.5, sage-3059/3064) | Q195 O2 S0 (#1798) static review of Fenton's fenton/q195-s0 85ae2be77 (security + CSP reports, receipts in s0-20261022) | CONCUR CONDITIONAL PASS, c30914; A1 M1 needs WOFF2 and summed-size tests, A2 F2/D7 misstate the ctrl+click gate, M2 retargets to DOCX save; N1-N4 non-blocking; D8 hash question stays with Mos; no queue row (mos-1361), no slot, harness not rerun
|
||||||
|
2026-10-23T00:52:58Z | Gyro (Codex gpt-6.1-sol, mos-1366/1367) | Vikunja571 Q235-Q237 O2 parent/W4 format-policy rewrite on gyro/editor-o2 | Canonical queue next gyro: nothing. Prepared P1-P6 and B1-B4 docs, baseline W4 import 1ac76a417; no product/build/browser/worker/private-file/queue/live action. Mos impact map fold precedes review/push handoff.
|
||||||
|
2026-10-23T01:37:07Z | Gyro (Codex gpt-6.1-sol, mos-1368/1372/1375) | Vikunja571 O2 parent/W4 revision complete for review | P1-P6/B1-B4 and A17-A41/Q1-Q16 folded; same-thread Case 2 lookups/support writes, human-set host-pushed off-host remote, Hermes/restore/counting/order/role gates. Static docs checks pass; old locator/projection mechanics retained, authority/access review reopened. No code, build/browser/worker run, private conversion, queue or live action. Direct Fenton/Mos/Sage handoff after push.
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,78 +1,91 @@
|
|||||||
# Q195 O2 W4: committed DOCX citations and access
|
# Q195 O2 W4: committed DOCX citations and Case 2 access
|
||||||
|
|
||||||
Design for Gitea #1799, assignment sage-3060/mos-1360. Owner Rocko;
|
Policy rewrite for Vikunja 571, mos-1366/1367/1368/1372/1375, Q234–Q237.
|
||||||
independent reviewer Megavolt. Normative parent: `e36bce352`,
|
Normative parent: `docs/plans/2026-10-21_q195-writing-editor.md` in the same revision.
|
||||||
`docs/plans/2026-10-21_q195-writing-editor.md`, blob
|
Original W4: Rocko/Megavolt, #1799, refactor 062646487, blob
|
||||||
`322ec50f2669cffc0f8256d6beffdaccc4d8dba8`, D12, D24-D26, W4 and W4b.
|
`2af460ab772f8d204598dc8cb79b3c161f311623`. Gyro writes this assigned revision; Fenton
|
||||||
This is a proposed implementation contract, not access enablement or a parser
|
independently reviews it. The reviewer-owned verdict file is untouched.
|
||||||
security PASS. Reviewer owns the separate verdict file; the author does not
|
Impact map: brain-redux d183246, `projects/mosaic-mvp/case2-docx-impact-map.md`, stack pin
|
||||||
write an approval there.
|
062646487. Sections 1/2/6/7 and A19/A20/A28 are reopened, plus part/view authorization
|
||||||
|
wording. Exact locator, package-validation and projection mechanics in sections 3–5 remain
|
||||||
|
from the reviewed baseline except their replaced per-document-scope wording.
|
||||||
|
|
||||||
## 1. Gates and compatibility
|
## 1. Confirmed format policy and approval gates
|
||||||
|
|
||||||
W4b implements this contract only after independent W4 APPROVE and Sage's
|
Q235–Q237 P1–P6 and mos-1372 D1/D2 settle the design basis: canon and playground story
|
||||||
accepted implementation brief, S0 and its other parent gates. A release must
|
files become DOCX, retaining universe/book and source scope. Type-folder notes, agent files,
|
||||||
ship extractor, resolver, authorization and sharing together; no partial
|
instructions, PRDs, character sheets, summaries and supporting documentation stay Markdown.
|
||||||
agent read rollout. Missing server readiness refuses every O2 read, resolve,
|
An unmarked-folder story is eligible; the human selects one story file at a time. New
|
||||||
share and flag. A human setting, pin or request field cannot assert readiness.
|
stories start directly as DOCX in the human-selected universe/book or playground, without a
|
||||||
W5 owns flags, not chapter writes. No agent execute, edit, replace, save,
|
Markdown precursor, under the same production-opening gate as import.
|
||||||
tracked-change or comment-writing operation is introduced.
|
|
||||||
|
|
||||||
Q36 / Vikunja 562 is OPEN. Production Markdown adoption remains closed under
|
The October 27 release stays Markdown. Production import/new-story opening waits for W4b,
|
||||||
mos-1358, independently of whether this design is approved. If Jason approves
|
W7, the post-10-27 release, the approved Case 2 PRD/brief amendment, Hermes retirement
|
||||||
superseded notices, a separate C2 reader/reply row must implement and pass
|
(#423 step 5) and configured off-host durability. The first real use on Melanie's books
|
||||||
them before adoption; otherwise Mos records Jason's disposition before any
|
also waits for Jason's scoped go. All starts are human-only; `library.convert` has no role
|
||||||
adoption brief proceeds. This document neither implements nor decides notices.
|
grant or agent request path and stays a hard wait unless an approved PRD changes it.
|
||||||
|
Nothing in this document authorizes conversion, new private story creation or deployment.
|
||||||
|
Q234's exact frame CSP, mos-1363 and S0 M1–M14 remain unchanged implementation gates.
|
||||||
|
|
||||||
Existing C2 Markdown, its line-cite schema, library grants and supporting-doc
|
mos-1372 D9 replaces the prior W4 O2-only-conversation, per-document-grant and per-send-share
|
||||||
writer remain unchanged. An authorized old Markdown original is historical
|
requirements for Case 2 lookups. Agents read converted stories through the normal Case 2
|
||||||
source, never the current DOCX or a permission to its later edits. No DOCX
|
lookups in any thread or room under the same live project/universe/source-scope checks as
|
||||||
paragraph is called a line. Following an adopted source from a C2 read,
|
Markdown canon/playground. They can then use existing supporting-Markdown write tools under
|
||||||
indexing it as Markdown, changing C2 replies or a synchronized Markdown
|
Q223. The agent never writes a story/DOCX/archive file. D9 is marked as a choice for Jason
|
||||||
projection requires a separately approved Case 2 amendment through Mos/Jason.
|
in PRD 1.17 approval; it is design text, not an already approved role/policy expansion.
|
||||||
W4b must test old C2 fixtures unchanged alongside the new discriminated DOCX
|
No code may rely on that changed requirement before the approved PRD and independent review.
|
||||||
contract. It may migrate only new O2 records, with a named schema edge Sage
|
|
||||||
allocates; it must not reinterpret existing line citations in place.
|
|
||||||
|
|
||||||
## 2. Trust and document identity
|
Human import commits the verified DOCX to a private staging ref first and obtains its
|
||||||
|
off-host push acknowledgment. It then creates/pushes the source archive move+mark through
|
||||||
|
new human-only bus plumbing on the C2-02/C2-03b writer, not two single-path saves. Finally
|
||||||
|
one host publication protocol advances writing-published and the catalogue under the
|
||||||
|
publication/read lock. No staged ID is reader-visible before catalogue CAS. Before that
|
||||||
|
switch, agents read the source at its pinned commit; sync cannot advance it early. After
|
||||||
|
it, only the current DOCX is a chapter. Pre-push failure leaves source Markdown unmoved;
|
||||||
|
after archive push, failure is a visible resumable pending operation, never an assertion
|
||||||
|
that nothing moved, a rollback push or Markdown revival. Old bytes/history remain.
|
||||||
|
|
||||||
The host reader alone opens `<dataRoot>/writing/<business>/<project>/`.
|
The archive is in the human-set source-repository folder, default archive/converted, with
|
||||||
Business, project and document are opaque IDs resolved through the host's
|
converted date, source commit/blob/path and replacement ID in the operation record. It is
|
||||||
owned manifest, never request paths. Each document has a stable ID and one
|
read-only in the Console. Explicit `archived` scope returns only requested authorized
|
||||||
canonical DOCX path; a rename does not change its identity. A copy/new import
|
records, always marked and non-canon; default/current queries never opt into it. An old
|
||||||
gets a new document ID and no inherited grant, share, pin or cache authority.
|
source lookup returns a typed conversion record and routes an authorized DOCX read, never
|
||||||
Origin metadata is evidence only. Copying a source does not launder access.
|
stale Markdown or fake DOCX lines. Historical line cites still verify at commit/blob and
|
||||||
|
show converted/historical state; archive access alone is not current story authorization.
|
||||||
|
|
||||||
A read snapshots one reachable committed manifest and its DOCX blob from the
|
Every conversion runs the pinned extractor before archiving and refuses unsupported output.
|
||||||
same commit. It never combines HEAD's manifest with another commit's DOCX.
|
An independently reviewed importer preserves every wiki token and front-matter key; metadata
|
||||||
The reader accepts only server-resolved commits reachable from that document's
|
moves to the canonical manifest (type/name/appears_in/relationships feed the index). Links
|
||||||
published history; arbitrary git objects and another document's same blob
|
resolve across Markdown/DOCX through owned aliases, not host paths. A lost link fails the
|
||||||
are not selectable. Historical access also requires the document's current
|
fidelity report. Plain links/front-matter values resolve or raise R4; unresolved chapter
|
||||||
live authorization. Removed history, missing blobs or missing extractor
|
embeds must not take the old silent attachment-drop path. Images/.canvas/.base remain attachments.
|
||||||
revisions refuse; there is no worktree, export or engine-memory fallback.
|
|
||||||
The commit/blob field is a locator, not an authority token.
|
|
||||||
|
|
||||||
The project's sole publication ref is `refs/heads/writing-published`; only
|
## 2. Document identity, order and freshness
|
||||||
the human writer advances it, atomically and without force updates. Each
|
|
||||||
commit contains the book manifest. For a document, its publication commits
|
|
||||||
are the first-parent commits on that ref that add or change its DOCX blob or
|
|
||||||
its canonical manifest entry (including deletion/reinstatement). The first
|
|
||||||
commit is a publication; a sibling-only save is not. `currentCommit` is the
|
|
||||||
latest such commit for this document at the captured ref tip. Version latest
|
|
||||||
selects that commit; a locator commit must be one of those publication commits,
|
|
||||||
not an arbitrary intervening project commit. Deleted document entries refuse
|
|
||||||
current reads, including history, until explicitly reinstated and granted.
|
|
||||||
Published history is exactly that document's reachable publication sequence.
|
|
||||||
A sibling save does not change its currentCommit, stale flag or cursor.
|
|
||||||
Staleness is still exact commit inequality within that document, even if a
|
|
||||||
human deliberately saves an earlier byte-identical blob as a new publication.
|
|
||||||
|
|
||||||
The writer's successful commit publishes atomically before Saved. A latest
|
Host code alone opens `<dataRoot>/writing/<business>/<project>/`. Opaque document IDs resolve
|
||||||
lookup begun after that receipt resolves that published commit, not an old
|
through the canonical manifest, never caller paths. Conversion preserves book/chapter identity
|
||||||
cache entry. A lookup already in progress remains internally on its captured
|
and scope, binding the original path/name as an alias to the DOCX ID. New stories get a fresh
|
||||||
commit. Return the captured version explicitly; never label it latest after
|
ID and the human-selected universe/book or playground. No format-based canon promotion.
|
||||||
observing a newer publish. Recheck live grants immediately before returning
|
The map tells authorized agents format, source scope, owned location and current version;
|
||||||
content, not just before asynchronous extraction.
|
archived entries are available only in explicit archived requests. No host paths/credentials.
|
||||||
|
|
||||||
|
A lookup snapshots the reachable committed manifest and DOCX blob from one publication.
|
||||||
|
No worktree, draft, archive or engine-memory fallback. `refs/heads/writing-published` is the
|
||||||
|
canonical served ref. A document's publications are the first-parent commits adding or
|
||||||
|
changing its blob/manifest entry; sibling-only saves do not change its currentCommit.
|
||||||
|
History locators name only such reachable publications, with current project/universe checks.
|
||||||
|
Deleted entries refuse until explicitly reinstated by an authorized human. New local saves
|
||||||
|
publish before acknowledgment. A lookup starting after an acknowledged save returns that
|
||||||
|
save or a later one and names it. A lookup already in flight stays on its captured version;
|
||||||
|
never label an observed older snapshot latest. Recheck live access before emitting text.
|
||||||
|
|
||||||
|
D10's ordered chapter-ID manifest drives manuscript paging and next_chapter after conversion,
|
||||||
|
replacing row216's initial path-order rule (RULINGS.md:32–34). Before the first conversion,
|
||||||
|
seed the order from that existing rule; replace each source entry with its DOCX identity in
|
||||||
|
place. A human reorder is a manifest commit. next_chapter never names an archive. Pending
|
||||||
|
unconverted files retain their legacy identity/scope until their individual publication
|
||||||
|
switch; no file has two working formats and new stories start as DOCX. Book-null notes
|
||||||
|
stay out of manuscript; hybrid exclusions and source-universe boundaries still apply.
|
||||||
|
|
||||||
## 3. Exact wire schema, version 1
|
## 3. Exact wire schema, version 1
|
||||||
|
|
||||||
@@ -81,7 +94,7 @@ commits/blobs are lowercase 40-hex Git object IDs in the repository's current
|
|||||||
SHA-1 object format. A future object format requires a new schema revision.
|
SHA-1 object format. A future object format requires a new schema revision.
|
||||||
Digest values are lowercase 64-hex SHA-256. Integers are safe nonnegative
|
Digest values are lowercase 64-hex SHA-256. Integers are safe nonnegative
|
||||||
JSON integers. No floats, coercion, duplicate JSON keys or implicit defaults
|
JSON integers. No floats, coercion, duplicate JSON keys or implicit defaults
|
||||||
except the explicitly listed request defaults below. These are proposed O2-only records.
|
except the explicitly listed request defaults below. These are proposed DOCX records for the Case 2 lookup/citation union.
|
||||||
|
|
||||||
A locator is exactly:
|
A locator is exactly:
|
||||||
|
|
||||||
@@ -214,10 +227,10 @@ extractor supports them; never guess equivalent namespaces.
|
|||||||
|
|
||||||
| Class | Exact part names | Story selector | Agent exposure |
|
| Class | Exact part names | Story selector | Agent exposure |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| body | word/document.xml | main | final by default, explicit grant |
|
| body | word/document.xml | main | final by default; existing project/universe access |
|
||||||
| footnote | word/footnotes.xml | w:footnote/@w:id | own story plus owning document grant |
|
| footnote | word/footnotes.xml | w:footnote/@w:id | own story; same project/universe access as its document |
|
||||||
| endnote | word/endnotes.xml | w:endnote/@w:id | own story plus owning document grant |
|
| endnote | word/endnotes.xml | w:endnote/@w:id | own story; same project/universe access as its document |
|
||||||
| comment | word/comments.xml | w:comment/@w:id | only explicit comment scope |
|
| comment | word/comments.xml | w:comment/@w:id | explicit part request; same project/universe access |
|
||||||
| layout | word/headerN.xml, word/footerN.xml (N positive decimal) | none | denied in v1 |
|
| layout | word/headerN.xml, word/footerN.xml (N positive decimal) | none | denied in v1 |
|
||||||
| supporting | separately declared non-story document | separate identity | C2 tools/scopes only; no DOCX scope inheritance |
|
| supporting | separately declared non-story document | separate identity | C2 tools/scopes only; no DOCX scope inheritance |
|
||||||
| opaque | media, styles, numbering, theme, fonts, custom XML, embedded objects | none | no raw bytes through O2 reader |
|
| opaque | media, styles, numbering, theme, fonts, custom XML, embedded objects | none | no raw bytes through O2 reader |
|
||||||
@@ -288,8 +301,9 @@ kind paragraph-mark-insert or paragraph-mark-delete with its revision ID;
|
|||||||
it never becomes a whole-paragraph deletion span. A mark-only insertion's
|
it never becomes a whole-paragraph deletion span. A mark-only insertion's
|
||||||
text stays in original; a mark-only deletion's text stays in final. Inline
|
text stays in original; a mark-only deletion's text stays in final. Inline
|
||||||
run revisions remain independent. No view edits or accepts/rejects changes.
|
run revisions remain independent. No view edits or accepts/rejects changes.
|
||||||
Original/markup and comments require separate scopes, so final body access
|
Original/markup and comments are explicit view/part requests under the same project/universe
|
||||||
never reveals hidden deletion/comment text. Revision author/date metadata
|
authorization; no per-document grant is added. A default final-body read never silently
|
||||||
|
includes deleted revisions or comment stories. Revision author/date metadata
|
||||||
is omitted from agent responses in v1.
|
is omitted from agent responses in v1.
|
||||||
|
|
||||||
Closed story/run leaf table (all names in w namespace unless stated):
|
Closed story/run leaf table (all names in w namespace unless stated):
|
||||||
@@ -372,7 +386,8 @@ plain text, and tokens cannot cross paragraph/view boundaries.
|
|||||||
## 6. Reading APIs, verification, paging and staleness
|
## 6. Reading APIs, verification, paging and staleness
|
||||||
|
|
||||||
These are proposed typed tool schemas over the existing runner socket, not
|
These are proposed typed tool schemas over the existing runner socket, not
|
||||||
native WordCraft MCP. Caller/session/business come from the bound broker.
|
native WordCraft MCP. The same reader backs Case 2 lookups in any authorized thread or
|
||||||
|
room under mos-1372 D9. Caller/session/business come from the bound broker.
|
||||||
Agents cannot override them using object fields.
|
Agents cannot override them using object fields.
|
||||||
|
|
||||||
- `editor_read_committed({project,document,version,textView,part,cursor,limit})`:
|
- `editor_read_committed({project,document,version,textView,part,cursor,limit})`:
|
||||||
@@ -412,14 +427,14 @@ without progress.
|
|||||||
|
|
||||||
Cursor is a host-authenticated opaque token binding principal, session,
|
Cursor is a host-authenticated opaque token binding principal, session,
|
||||||
project/document, commit/blob, extractor, view, part, next ordinal, the complete
|
project/document, commit/blob, extractor, view, part, next ordinal, the complete
|
||||||
authority revision vector defined in section 7 and expiration (5 minutes). It carries no plaintext content.
|
project/universe authorization and format-publication revision vector defined in section 7 and expiration (5 minutes). It carries no plaintext content.
|
||||||
Tampering, reuse by another session, wrong request parameters or a revoked
|
Tampering, reuse by another session, wrong request parameters or a revoked
|
||||||
scope refuses. A latest cursor continues its captured snapshot with stale
|
scope refuses. A latest cursor continues its captured snapshot with stale
|
||||||
metadata if a save intervenes; starting again with null cursor returns the
|
metadata if a save intervenes; starting again with null cursor returns the
|
||||||
new publication. Cursor is not a capability and grants are rechecked every
|
new publication. Cursor is not a capability and grants are rechecked every
|
||||||
page. Repeated ordinal ranges are stable within one committed projection.
|
page. Repeated ordinal ranges are stable within one committed projection.
|
||||||
|
|
||||||
Resolver steps: authorize the current principal tuple, live scopes and exact/historical share (there is no separate undefined historical-view scope); load
|
Resolver steps: authorize the current principal, live project/universe/source scope and publication membership; load
|
||||||
that commit's manifest/blob; validate package; run the exact pinned extractor;
|
that commit's manifest/blob; validate package; run the exact pinned extractor;
|
||||||
select exact part/story/ordinal and mandatory XML-ID value; select code-point range;
|
select exact part/story/ordinal and mandatory XML-ID value; select code-point range;
|
||||||
require literal quote equality and SHA-256(UTF-8 quote) equality. Require both
|
require literal quote equality and SHA-256(UTF-8 quote) equality. Require both
|
||||||
@@ -431,14 +446,13 @@ an explicit old-version label. If current grant no longer allows it, even
|
|||||||
old quote resolution refuses and the UI hides cached content.
|
old quote resolution refuses and the UI hides cached content.
|
||||||
|
|
||||||
Errors: `editor-context-unavailable` for missing readiness; `editor-access-refused`
|
Errors: `editor-context-unavailable` for missing readiness; `editor-access-refused`
|
||||||
for absent ownership/grant/share (same response for nonexistent or foreign IDs);
|
for absent live project/universe authorization (same response for nonexistent or foreign IDs);
|
||||||
`editor-document-unsupported` for parser limits or unsupported features after
|
`editor-document-unsupported` for parser limits or unsupported features after
|
||||||
authorization; `editor-version-unavailable` for authorized missing history or
|
authorization; `editor-version-unavailable` for authorized missing history or
|
||||||
extractor; `editor-citation-invalid` for locator/quote mismatch;
|
extractor; `editor-citation-invalid` for locator/quote mismatch;
|
||||||
`editor-cursor-invalid` for invalid paging; `editor-range-too-large` for size.
|
`editor-cursor-invalid` for invalid paging; `editor-range-too-large` for size.
|
||||||
The exact refusal envelope is `{ok:false,error:{code,message}}`; code is one
|
The exact refusal envelope is `{ok:false,error:{code,message}}`; code is one
|
||||||
of those enum strings or editor-policy-conflict/editor-sharing-unsupported
|
of those enum strings or editor-policy-conflict (409, stale catalogue/settings revision), and message is fixed server text for that code (no user
|
||||||
(both 409, defined in section 7), and message is fixed server text for that code (no user
|
|
||||||
input). Both missing/foreign and ungranted IDs use the same code/message/status
|
input). Both missing/foreign and ungranted IDs use the same code/message/status
|
||||||
403. Syntax errors before identity lookup use editor-citation-invalid, 400;
|
403. Syntax errors before identity lookup use editor-citation-invalid, 400;
|
||||||
context unavailable is 503, cursor-invalid 400, version unavailable 409,
|
context unavailable is 503, cursor-invalid 400, version unavailable 409,
|
||||||
@@ -446,417 +460,131 @@ unsupported/range-too-large 422. Successful tools return `{ok:true,result}`
|
|||||||
where result is the defined response; errors never include result/partial
|
where result is the defined response; errors never include result/partial
|
||||||
rows. Return no source text, XML, path or untrusted parser error in refusals.
|
rows. Return no source text, XML, path or untrusted parser error in refusals.
|
||||||
|
|
||||||
## 7. Authority data, dedicated sessions and sharing
|
|
||||||
|
|
||||||
### 7.1 Scope and principal records
|
### 6.1 Case 2 query and citation adapters
|
||||||
|
|
||||||
O2 context is permitted only in newly created **O2-dedicated conversations
|
Keep `library_find`, `library_get`, `library_search`, `library_manuscript` and the universe
|
||||||
and execution sessions**. Existing C2 threads/sessions cannot be converted,
|
lookup. Host adapters join Markdown metadata/read results and the committed DOCX extractor
|
||||||
attached to O2 context or resumed/forked into O2 mode; new IDs and a fresh
|
into one typed, scope-filtered index; only current identities enter normal lookups. A request
|
||||||
empty context are mandatory. There is no mixed-thread turn. The UI offers
|
on a converted alias returns its conversion record and the authorized DOCX result. Every
|
||||||
"Open dedicated writing conversation", never silently changes an existing
|
answer names format, store/owned ID and captured commit. No loss of chapter search/manuscript
|
||||||
chat's permissions. Existing C2-02 supporting-doc writes and C2-06 replies
|
or supporting-doc workflow is accepted. Same project/universe/source-scope rules apply in
|
||||||
retain their semantics. The narrowing below belongs only to this explicitly
|
all threads/rooms; archive/draft scope never becomes canon because its format is DOCX.
|
||||||
opted-in O2 mode, closing review M1 without a Case 2 amendment. It changes
|
|
||||||
neither the Case 2 schema nor the meaning of its replies/line citations.
|
|
||||||
|
|
||||||
Authorization principal is a tuple, not a seat's display name:
|
DOCX pages use paragraph locators and opaque cursors, not invented line equivalents.
|
||||||
`{business,human,agentInstance,conversation,executionSession}`. human is the
|
Retain section 6's 64-KiB/1..100 paragraph bounds (default20); human reply limits still apply.
|
||||||
stable authenticated identity that owns the O2 conversation; agentInstance
|
A manuscript cursor binds ordered-manifest commit, the selected document publication vector,
|
||||||
and executionSession come from its bound broker run. The request cannot
|
principal/request/scope revisions and expiry. Resume only that snapshot with current access;
|
||||||
supply/replace them. All human readers and all agent lookups require live
|
changed/foreign cursor refuses. next_chapter uses the next visible current manifest ID,
|
||||||
R5 project/universe access plus the O2 grant below; role files grant the
|
never an archive or a guessed sort of DOCX names. Index/cache keys include local publication
|
||||||
operation only. The business owner is not an implicit reader of someone
|
and extractor revisions; no minute-old Markdown refresh window is copied to DOCX.
|
||||||
else's private conversation. A viewer can read only their authorized human
|
|
||||||
view, never write a share/settings change or invoke an agent by sharing.
|
|
||||||
An owner/collaborator with current project write access may share within
|
|
||||||
their own readable O2 scope. Agent scope and sharing human scope intersect;
|
|
||||||
a human cannot share a part or view they lack.
|
|
||||||
|
|
||||||
O2 scopes live in the new append-only bus table writing_access_events, not
|
C2-06's checked cite union preserves legacy `{path,commit,lines,quote,as?}` for Markdown and
|
||||||
access.json or role-file wildcard changes. Proposed human-only verb
|
adds `{kind:"docx",locator,as?}` where locator is section3's exact range/selection. Never infer
|
||||||
`editor.access.set({project,document,subject,scope,expectedRevision})` takes
|
a cite kind from a .docx suffix or parse DOCX as lines. The host checks project/universe,
|
||||||
subject exactly `{kind:"human"|"agent",id}`; agent id is the business's
|
source canon/playground/archive status, fetched provenance, quote and commit before message
|
||||||
bus agent **instance ID**, equal to principal.agentInstance, never a role
|
storage. requireCitation and as:canon apply to both; historical converted/archived sources
|
||||||
definition ID or a seat display name. scope is exactly
|
cannot assert current canon. The host reads Mosaic-Agent trailers from the correct source
|
||||||
`{enabled,parts,views,history,mayShare}`. parts is a sorted unique nonempty
|
repository or writing-store publication, never trusts an agent author field. Console and
|
||||||
subset of body/footnote/endnote/comment (all stories within the selected
|
the shared reply renderer show format, locator/lines, version, staleness and converted state.
|
||||||
class); views is a sorted unique nonempty subset final/original/markup;
|
C2-18 Discord remains a separate ruled delivery task, not enabled by a shared renderer.
|
||||||
history and mayShare are booleans. mayShare must be false for agent subjects.
|
|
||||||
enabled=false revokes all access; even its otherwise populated scope cannot
|
|
||||||
authorize. No wildcards or implicit note/comment inheritance. A comment
|
|
||||||
requires parts including comment and the requested view. history=true permits
|
|
||||||
older publications subject to a matching share; history=false permits only
|
|
||||||
the current publication. The document is always explicit.
|
|
||||||
|
|
||||||
Only the existing business-owner human proof may write these policy grants,
|
## 7. Existing Case 2 authority, remote durability and restore
|
||||||
through the existing trusted human CLI or authenticated write-enabled Console
|
|
||||||
transport, with the existing origin/session/proof checks. No new proof file,
|
|
||||||
caller or exemption. Not tester, agent, viewer or collaborator policy writes.
|
|
||||||
Sharing and scope are different: an authorized collaborator may send context
|
|
||||||
but cannot change grants. expectedRevision is the latest sequence for that
|
|
||||||
business/project/document/subject, zero when none. Compare, append and audit
|
|
||||||
are atomic; conflict returns editor-policy-conflict (409, fixed message).
|
|
||||||
Receipt is `{ok:true,result:{id,revision,previousRevision,scopeDigest}}`, where
|
|
||||||
revision is the appended seq, id is host-generated, and scopeDigest is SHA-256
|
|
||||||
of canonical scope JSON using section 3 serialization. Missing grant denies.
|
|
||||||
|
|
||||||
Each access decision records an authority vector exactly
|
### 7.1 Access and supporting writes (reopened M1)
|
||||||
`{restoreEpoch,humanAccess,agentAccess,projectAccess,threadAccess,sharingPolicy,share}`.
|
|
||||||
humanAccess and agentAccess are the respective latest writing_access_events
|
|
||||||
seq values; projectAccess is the existing R5 access revision; threadAccess
|
|
||||||
is the latest O2 conversation membership-event seq; sharingPolicy is the
|
|
||||||
latest writing_policy_events seq; share is the exact writing_shares seq.
|
|
||||||
restoreEpoch is the independent restore-fence epoch in section 7.5.
|
|
||||||
Missing inputs deny rather than zero-default except initial policy explicitly
|
|
||||||
materialized by the human writer as the default. A cursor binds every value;
|
|
||||||
any change invalidates it. Each new lookup reevaluates rights, including a
|
|
||||||
revocation between asynchronous extraction and response emission.
|
|
||||||
|
|
||||||
### 7.2 One human per context; settings and chip requests
|
Reuse existing bound business/project/universe access, live holder/role and source scope.
|
||||||
|
No private O2 conversation ID, per-document access table or send/share token gates a Case 2
|
||||||
|
lookup. Any existing authorized thread/room may use the checked reader and normal library
|
||||||
|
tools. No arbitrary native WordCraft MCP, execute, open/save or raw filesystem/git tool is
|
||||||
|
added. The host store is never mounted in a worker. Rendered/extracted content travels over
|
||||||
|
the ordinary authorized Case 2 tool/message path and existing transcript/run-record policy;
|
||||||
|
the withdrawn private-only transcript/output rule cannot forbid that documented workflow.
|
||||||
|
Grant loss blocks later lookups through existing checks; do not promise erasure of earlier
|
||||||
|
delivered text or rewrite immutable run evidence. This is the D9 choice for PRD approval.
|
||||||
|
|
||||||
An O2 conversation has exactly one owner human and one agent instance. No
|
The existing `library_doc_write`/`library_doc_delete` still require library.write plus the
|
||||||
second human joins it in v1: a thread-share attempt refuses
|
live supporting-repo Gitea grant and supportingPath before git. They operate only on human-
|
||||||
editor-sharing-unsupported (409), rather than borrowing the sender's grants
|
marked supporting Markdown, with the existing size/base-CAS/seat-author/push/notice/revert
|
||||||
for someone else. A second human starts a separate O2 conversation, supplies
|
rules. An agent can read a DOCX story and update its character sheet in the same authorized
|
||||||
their own grant/share and gets no previous content. This is a new O2 mode,
|
thread. There is no agent write to DOCX, original story, archive or conversion manifest.
|
||||||
not a restriction on existing C2 sharing. Human and agent must still have
|
The archive prefix wins over supporting globs; conflicts refuse mapping. Format/status/type
|
||||||
matching business/project/universe rights. Read-only previews cannot send.
|
notes in the six creative contracts replace stale 'every item cites lines' wording with
|
||||||
|
free chat plus optional checked line/DOCX citations under requireCitation. No per-document
|
||||||
|
export grant or O2-only session is a hidden prerequisite.
|
||||||
|
|
||||||
Human-only `editor.sharing.set({conversation,mode,expectedRevision})` is
|
The cursor authority revision is the server's current project grant, universe/mapping/scope
|
||||||
available only to that authenticated owner with current write access over
|
revision and format-publication generation for the bound caller/session. It contains no
|
||||||
the same trusted write transports. mode is off/visible-chip-per-send/
|
sharing human or writing_access_events/writing_shares sequence. Recheck before every page,
|
||||||
conversation-current. It atomically appends writing_policy_events and returns
|
resolution, index hit and message insertion. Scope revocation and format changes invalidate
|
||||||
`{ok:true,result:{id,revision,previousRevision,mode}}`. Default is the explicit
|
cached authorization; metadata for missing/foreign IDs uses the same refusal as before.
|
||||||
visible-chip-per-send policy on new conversation creation. Selecting off
|
|
||||||
immediately invalidates **all** prior shares, reads, resolves and cursors for
|
|
||||||
that conversation, not only new sends. Selecting another mode later does
|
|
||||||
not revive shares from the earlier policy revision. No pin changes a mode.
|
|
||||||
|
|
||||||
In visible-chip-per-send the human sends exactly
|
### 7.2 Selection convenience and ordinary messages
|
||||||
`{conversation,message,expectedPolicyRevision,chip}` via the human send path.
|
|
||||||
message is human-authored free-chat text; W4b's bounded human API handles it,
|
|
||||||
never an agent-supplied impersonation. chip is null or one of:
|
|
||||||
|
|
||||||
- `{kind:"range",document,baseCommit,selection}` where selection is one
|
Keep Q233's human-only setting, default a visible removable chip on each send. A chip may
|
||||||
docx-range/docx-selection locator, with its business/project/document/
|
attach only a verified committed locator/version, never unsaved selection text. It helps the
|
||||||
commit equal to the server-owned conversation/document and baseCommit.
|
writer point at a passage; it neither grants nor limits the agent's ordinary project/universe
|
||||||
- `{kind:"document",document,baseCommit,parts,views,history}` selecting a
|
lookup rights and does not freeze a later latest lookup to that older commit. The sent cite
|
||||||
whole-document **exact publication**, with explicit part/view lists and
|
remains immutable historical evidence. Multi-human/thread/room behavior follows existing Case 2
|
||||||
history boolean constrained by both grants.
|
permission checks, not a new one-human conversation restriction. Saved-context/pin records
|
||||||
|
remain on the bus through their reviewed schema, with no share-token authority layer.
|
||||||
|
|
||||||
Both chips require a server-issued human editor selection token as an
|
### 7.3 Host-only off-host remote (replaces the ban)
|
||||||
additional required `selectionToken` key. It binds authenticated login,
|
|
||||||
conversation, document, baseCommit, saved editor model revision, and either
|
|
||||||
exact locator or whole-document scope digest, expires in 2 minutes and is
|
|
||||||
single-use. The human editor adapter creates it only after exact mapping to
|
|
||||||
the committed projection. The request supplies no draft text or engine path
|
|
||||||
for mapping; mismatched/edited selection fails locally and server-side.
|
|
||||||
A stale base or document change before send refuses, requiring a fresh
|
|
||||||
visible chip; an old citation remains resolvable through its already-sent
|
|
||||||
share while authorized. Null chip sends no editor context. Before readiness,
|
|
||||||
the chip says unavailable and sends no document ID, title, path or selection.
|
|
||||||
|
|
||||||
A range share permits only editor_resolve_citation for that exact locator
|
`editor.remoteURL` is a human-only setting, default unset. No same-host bare/filesystem/loopback
|
||||||
(or a range wholly contained within it with newly verified quote/digest).
|
remote is the default or qualifies as off-host durability. The human selects an off-stack-host
|
||||||
It always refuses editor_read_committed, since rows would expose surrounding
|
private destination (for example private Gitea) and separately configures host-only auth.
|
||||||
text. A document exact share allows paging only its named publication,
|
Only the host process pushes. No seat token can list/fetch/clone/fork/push the writing repo,
|
||||||
parts/views; it never grants future saves. No implicit body-to-note/comment
|
no seat gets its credential, and no raw Gitea grant or store mount is created. Validate the
|
||||||
or final-to-markup expansion occurs.
|
owned remote, TLS/host policy and off-host storage identity; reject URL userinfo, unexpected
|
||||||
|
remotes/object alternates and non-fast-forward updates. No silent fallback or force push.
|
||||||
|
|
||||||
conversation-current is an explicit human policy with a persistent visible
|
Every writing-store commit pushes there. Agents read the local publication immediately;
|
||||||
indicator and a required whole-document chip. The same chip fields bind
|
receipts/UI distinguish local commit and remote pending/failed/synced. Missing remote blocks
|
||||||
baseCommit and scope, but the share record has versionMode=latest: baseCommit
|
production opening. Before source archive push, the staged DOCX must have remote acknowledgment.
|
||||||
is the acknowledged publication at issuance, not a future-version ceiling.
|
A failed later push keeps local commits, queues bounded host retry/readback and shows failure;
|
||||||
The next authorized latest lookup after Saved follows currentCommit within
|
it never rolls back the local story. Source archives push through their separate human
|
||||||
the granted part/view/history bounds. This exception to exact-version sharing
|
library writer. The configured retry deadline is human-only (default30s, 1s..300s).
|
||||||
exists only in this explicit mode. Range chips are refused in this mode,
|
Remote/provisioning changes require the normal owner authority, never this design execution.
|
||||||
not silently upgraded. Pins and earlier exact shares never become latest.
|
The remote exception is for story git history/manifest; generic stack copies/releases are
|
||||||
|
not story backups and contain no host credentials. Normal Case 2 output/notes follow the
|
||||||
|
existing project's approved storage/sharing policy; the former blanket no-backup/no-remote
|
||||||
|
rule is withdrawn. PRD 1.17 explicitly presents this D7/C4 change to Jason.
|
||||||
|
|
||||||
Latest shares expire on explicit policy revocation, owner grant loss, O2
|
### 7.4 Conversion events, rollback --restore and irreversible recovery
|
||||||
conversation close or **execution-session end/clear**. This means the new
|
|
||||||
O2 execution session, not the Console login, bus connection or a C2 thread
|
|
||||||
session. Relaunch/clear requires a fresh chip; a dropped socket/login does
|
|
||||||
not silently widen or prolong one. Exact shares may remain verifiable across
|
|
||||||
execution sessions through their same human conversation while live policy,
|
|
||||||
history permission and grants hold, but never supply replay context to a
|
|
||||||
new agent session without a new share. Their scope is citation verification
|
|
||||||
only after the issuing execution session ends. No cross-human context reuse.
|
|
||||||
|
|
||||||
### 7.3 Stored share schema
|
W7 owns `writing_conversion_events`: a STRICT append-only table with seq INTEGER PRIMARY KEY,
|
||||||
|
at TEXT, business/project/document/operation_id/stage TEXT, record_ref/record_digest TEXT;
|
||||||
|
All fields except seq are NOT NULL; operation_id+stage is unique, no update/delete. The private host journal/record contains source
|
||||||
|
commit/blob/path, archive path/commit, DOCX commit and conversion date; the row is metadata
|
||||||
|
and never prose/credentials. Records are flushed before their bus references. Table rows
|
||||||
|
join stack-release COUNTED and T46 exactly once, so post-backup conversion events contribute
|
||||||
|
to --events and the existing restore approval/counting behavior. No new private conversation,
|
||||||
|
per-document grant or per-send share tables are created for D9.
|
||||||
|
|
||||||
The immutable writing_shares payload is exactly
|
Three recovery cases are required: (1) crash after durable DOCX staging but before archive
|
||||||
`{version,id,restoreEpoch,business,project,document,conversation,executionSession,message,
|
push, (2) crash after archive push before publication, and (3) rollback --restore from a
|
||||||
human,agentInstance,mode,versionMode,baseCommit,blob,extractor,scope,selection,
|
pre-conversion bus backup while archive commits and O2 documents remain. The source is pinned
|
||||||
authority,policyRevision,issuedAt}`. version=1; IDs use section 3 grammar;
|
until final publication in cases1/2; after archive push state is visibly pending, never
|
||||||
mode is the policy at issuance; versionMode is exact/latest; baseCommit/blob
|
'original untouched'. Case3 drops conversion rows only through the counted/approved restore
|
||||||
are the acknowledged snapshot and extractor is its exact pinned revision.
|
path. The durable host conversion journal/format registry is not restored from that older bus
|
||||||
scope is `{parts,views,history}` as above; selection is the verified locator
|
backup. A compatible controller compares journal, both git histories, remote acknowledgment
|
||||||
for a range, otherwise null. authority is the complete revision vector at
|
and restored metadata before lookups/writes resume; it reconstructs missing metadata through
|
||||||
issuance; its share field equals this row's seq (assigned atomically).
|
new recovery events without reviving Markdown or any old access grant. If reconciliation
|
||||||
restoreEpoch must equal authority.restoreEpoch and the live independent
|
cannot prove a single current identity/version, refuse that project's lookups and surface the
|
||||||
fence. issuedAt is canonical UTC millisecond ISO timestamp. policyRevision equals
|
pending operation to the human. Do not replay chapter text into an old index or hide event loss.
|
||||||
authority.sharingPolicy. message names a new writing_messages row, not a C2
|
Incompatible old binaries cannot activate converted projects through the supported controller;
|
||||||
message. A unique `(conversation,message,document)` constraint and operation
|
raw privileged rollback tampering is outside the guarantee. Never rewrite git/run history.
|
||||||
idempotency key prevent duplicate grants on retry. No user-provided human,
|
|
||||||
agentInstance, authority, issuedAt, blob or share id is accepted.
|
|
||||||
A scope decrease/revocation denies even historical shares; an unrelated new
|
|
||||||
policy revision also invalidates prior policy-bound shares. A human who
|
|
||||||
needs them again explicitly reshares. Missing session/share is no context.
|
|
||||||
|
|
||||||
### 7.4 Dedicated storage and every output surface
|
|
||||||
|
|
||||||
Every turn receiving O2 context runs with the new O2-only allowlist of
|
|
||||||
read/resolve/flag plus its dedicated conversation reply. No generic file,
|
|
||||||
shell, git, supporting-doc writer or arbitrary outgoing tool is available.
|
|
||||||
This narrows only new O2 sessions, never C2 turns. All agent output from such
|
|
||||||
a turn is conservatively O2-derived; it stays in the dedicated conversation
|
|
||||||
with the union of the document provenance/scopes. No semantic quote detector
|
|
||||||
or agent self-labelling supplies this boundary. Human text and titles in that
|
|
||||||
conversation use the same dedicated storage, so a human pasting an O2 passage
|
|
||||||
cannot accidentally route it into an old renderer. O2 replies never enter
|
|
||||||
C2-06 processing. An O2 flag is metadata stored by W5, not a story edit.
|
|
||||||
|
|
||||||
| Existing surface | Required O2 behavior |
|
|
||||||
| --- | --- |
|
|
||||||
| threads/<business>/<thread>/session and claude-projects | no O2 content, prompt, model transcript, title or derived reply |
|
|
||||||
| threads/<business>/<thread>/sessions/<session>/session and claude-projects | same; O2 mode never binds these native stores |
|
|
||||||
| session-workspaces/<business>/<instance>/<session> | no O2 text or exports; no store mount |
|
|
||||||
| launches/<business>/<run> including bundle, turns, runner.log and session | opaque IDs/status only, never O2 prompts/output; host transient O2 adapter instead |
|
|
||||||
| bus events, messages, message_threads and existing sessions rows | no O2 text/titles/quotes; only fixed readiness/status audit with opaque IDs if needed |
|
|
||||||
| Console legacy thread view | no O2 rows; dedicated writing view reauthorizes every read |
|
|
||||||
| CLI thread, talk, follow and raw-session tools | no O2 content; unsupported mode refuses, not generic rendering |
|
|
||||||
| Discord journal.mjs/context.mjs and control-board Discord delivery | no O2 conversation subscriptions/context/output; fixed unavailable notice only |
|
|
||||||
| <dataRoot>/runs write-once evidence | never O2 text, prompts, titles, excerpts, stdout/stderr or derived output; only opaque run status |
|
|
||||||
| bus-host/sessions.json, launch logs and activity projections | IDs/liveness only, no document or conversation title |
|
|
||||||
|
|
||||||
Host-only `<dataRoot>/writing-context/` (0700 owner, no generic mount/remote)
|
|
||||||
holds the immutable dedicated message/share objects defined below, transient
|
|
||||||
O2 adapter material and any unavoidable encrypted native transcript. Object
|
|
||||||
files are regular 0600 owner files, no symlink/hardlink aliases. This is an
|
|
||||||
O2-classified content store; it is never included in the bus release backup,
|
|
||||||
post-attempt store, stack-copy, rehearse input or generic backup. Revocation
|
|
||||||
changes permission at read time, never rewrites a write-once run record. It is keyed to O2 session, not an alias/symlink into seat stores.
|
|
||||||
Release readiness requires an independently tested adapter that prevents
|
|
||||||
plaintext native persistence/logging outside this boundary, including crash
|
|
||||||
and timeout paths. If either Pi or Claude cannot meet it, that harness's O2
|
|
||||||
tools stay off; do not expose the session then attempt post-hoc redaction of
|
|
||||||
write-once run records. Readiness is per adapter. No O2 text enters immutable
|
|
||||||
legacy evidence, even briefly. Stored dedicated replies are authorized afresh
|
|
||||||
at read time; live grant loss hides cached UI content and prevents prompt
|
|
||||||
replay/fork. Revocation cannot erase already delivered knowledge and the UI
|
|
||||||
must not promise that it can.
|
|
||||||
|
|
||||||
O2-derived exports, extraction indexes, caches, previews, source copies and
|
|
||||||
git history retain document classification outside generic roots and C2
|
|
||||||
library mappings. O2 repositories have **no git remotes**. No push, mirror,
|
|
||||||
fork, plaintext backup or remote replication of an O2 repository is allowed,
|
|
||||||
including through human credentials; no seat Gitea account can discover,
|
|
||||||
list, fork or clone one. Backup transport is out of scope and disabled, not
|
|
||||||
an implied exception. Stack-copy/release copies source code and extractor
|
|
||||||
artifacts only, never writing/, writing-context/, writing-control/, O2 content
|
|
||||||
objects, exports or repository object directories. The separate release bus
|
|
||||||
backup retains metadata rows only, under the private-store rules below;
|
|
||||||
it is not a source copy or permission to read context. No raw O2 Gitea grant may be minted.
|
|
||||||
Validate absence of remotes at store creation, before save/read and activation;
|
|
||||||
a new remote or object alternate disables O2, rather than trusting a read-only
|
|
||||||
mount. Symlinks, hardlinks, alternate worktrees and parent mounts must not
|
|
||||||
expose it to generic tools. Native engine APIs remain human-only.
|
|
||||||
|
|
||||||
### 7.5 Named migration and rollback contract
|
|
||||||
|
|
||||||
W4b adds the following new STRICT append-only bus tables (seq INTEGER primary
|
|
||||||
key, at TEXT canonical timestamp, id TEXT unique, all other fields NOT NULL
|
|
||||||
unless stated). Each row also has restore_epoch TEXT NOT NULL, equal to the
|
|
||||||
independent current fence epoch at write time. Every update/delete/replace
|
|
||||||
refuses; latest seq **within that epoch** is state.
|
|
||||||
JSON columns contain the exact canonical schema named above, not arbitrary
|
|
||||||
unvalidated JSON. No existing C2 messages/events/sessions column changes.
|
|
||||||
|
|
||||||
| Table | Additional columns and key |
|
|
||||||
| --- | --- |
|
|
||||||
| writing_access_events | business TEXT, project TEXT, document TEXT, subject_kind TEXT (human/agent), subject_id TEXT, by_human TEXT, previous_revision INTEGER, scope_json TEXT, operation_id TEXT UNIQUE; latest per document/subject |
|
|
||||||
| writing_conversations | business TEXT, project TEXT, owner_human TEXT, agent_instance TEXT; one creation row per id, private O2 identity only |
|
|
||||||
| writing_conversation_events | conversation TEXT FK, op TEXT (close), by_human TEXT; latest membership/close revision, creation seq is initial threadAccess |
|
|
||||||
| writing_execution_sessions | conversation TEXT FK, execution_session TEXT UNIQUE, adapter_revision TEXT; no native transcript path |
|
|
||||||
| writing_session_events | execution_session TEXT FK, op TEXT (end/clear), by_principal TEXT; terminal event invalidates latest shares |
|
|
||||||
| writing_policy_events | conversation TEXT FK, mode TEXT, by_human TEXT, previous_revision INTEGER, operation_id TEXT UNIQUE |
|
|
||||||
| writing_messages | conversation TEXT FK, execution_session TEXT FK nullable for human-only messages, from_kind TEXT (human/agent), from_id TEXT, content_ref TEXT, content_digest TEXT, operation_id TEXT UNIQUE |
|
|
||||||
| writing_shares | conversation TEXT FK, message TEXT FK, document TEXT, payload_ref TEXT, payload_digest TEXT, operation_id TEXT UNIQUE; UNIQUE(conversation,message,document) |
|
|
||||||
|
|
||||||
Each table also has business/project columns if not otherwise listed; FK and
|
|
||||||
application checks require agreement, not just ID existence. The canonical message content object is exactly `{version:1,business,project,row,nonce,body,provenance}`:
|
|
||||||
row is the owning writing_messages row ID; nonce is fresh cryptographically
|
|
||||||
random 32-byte lowercase hex, stored only inside the private object, not its
|
|
||||||
metadata backup. body is
|
|
||||||
the complete human/agent message string; provenance is an array of `{document,share,commit,blob,extractor}`,
|
|
||||||
sorted by document/share; every entry requires live scopes. The share content
|
|
||||||
object is exactly `{version:1,business,project,row,nonce,payload}`, where row
|
|
||||||
is its writing_shares row ID, nonce has the same fresh/private rule, and
|
|
||||||
payload is the full section 7.3 record including any quoted selection.
|
|
||||||
Neither message bodies nor share payloads/quotes enter bus.sqlite, WAL,
|
|
||||||
events, SQL error logs or backup manifests. Human messages with no O2
|
|
||||||
attachment have provenance=[] but use the same private content store.
|
|
||||||
content_ref/payload_ref are opaque 64-hex object names, not paths; their
|
|
||||||
corresponding digest equals SHA-256 of the exact canonical UTF-8 object.
|
|
||||||
Objects reside at writing-context/objects/<business>/<row>/<digest>.json;
|
|
||||||
row/business/project must match both reference metadata and the authorized
|
|
||||||
caller. No cross-business or cross-row deduplication; retention is per owning
|
|
||||||
row and cannot delete another business's object. The private random nonce
|
|
||||||
prevents a metadata digest from confirming a guessed short body. No remote or
|
|
||||||
release-backup copy. Write/flush the immutable object before committing its
|
|
||||||
bus reference. A failed transaction leaves only an inaccessible orphan,
|
|
||||||
never a visible partial message/share; a missing or mismatched object refuses.
|
|
||||||
Object reads always require current authority, not knowledge of a digest.
|
|
||||||
No
|
|
||||||
existing renderer queries these new tables; generic bus recordEvent and
|
|
||||||
recordTask cannot write their rows. Access/policy/shares use only the trusted
|
|
||||||
handlers and atomic transactions. Grant seq values are table-specific, with
|
|
||||||
kind-qualified revision vector fields; never compare unrelated seq counters.
|
|
||||||
|
|
||||||
Sage allocates the schema edge; migration creates these empty tables and
|
|
||||||
triggers, with no backfill/conversion of C2 citations, messages or raw sessions.
|
|
||||||
Production adoption stays refused. The writer registers new documents without
|
|
||||||
creating grants; the owner explicitly sets both human/agent document scopes.
|
|
||||||
O2 session creation and its default policy are one atomic operation behind
|
|
||||||
owner write proof; receipt `{id,executionSession,policyRevision}` contains no
|
|
||||||
content. No legacy thread/session can be attached by guessed ID.
|
|
||||||
|
|
||||||
Old release rollback must not render O2 data. The new store schema version
|
|
||||||
normally makes old binaries refuse opening it, but security does not depend
|
|
||||||
on that: even a restored pre-W4b database reader can see only its unchanged
|
|
||||||
legacy tables with no O2 content. O2 messages/share/provenance remain in new
|
|
||||||
tables, never a tagged body in existing messages. Activating a pre-W4b copy
|
|
||||||
disables O2 context, never converts dedicated conversations to C2 or exports
|
|
||||||
transcripts for compatibility. O2 repositories/stores remain outside copies.
|
|
||||||
A rollback probe uses recognizable secret fixture text in O2-only content objects,
|
|
||||||
then invokes old Console/CLI/Discord/raw-session renderers: none may emit it,
|
|
||||||
its title, quote or prompt. No live rollback is part of acceptance testing.
|
|
||||||
|
|
||||||
#### Release backup, restore counting and independent revocation fence
|
|
||||||
|
|
||||||
The existing release behavior must be explicitly accounted for: at this base
|
|
||||||
`scripts/stack-release.sh:474-493` copies bus.sqlite into
|
|
||||||
`<dataRoot>/backups/stack/<ACT>/bus/`; restore_store at :498ff moves current
|
|
||||||
bus/ to `<dataRoot>/bus.post-attempt-<stamp><suffix>/`. rehearse reads backup
|
|
||||||
stores, and release never prunes them. These paths remain **O2-classified
|
|
||||||
metadata stores** even though content/quotes are outside SQLite. Directories
|
|
||||||
are 0700 owner and files (including SQLite/WAL/SHM if present) 0600 owner,
|
|
||||||
with ownership, symlink/hardlink and generic mount checks. No remote, mirror,
|
|
||||||
seat token access or generic export. rehearse may read metadata for validation
|
|
||||||
only and cannot load content objects, emit quotes or restore readiness.
|
|
||||||
|
|
||||||
Release does not silently delete evidence. A separate explicit human/ops
|
|
||||||
retention action may prune a stopped backup/post-attempt tree only after
|
|
||||||
checking it is not the selected recovery set or needed restore evidence,
|
|
||||||
recording its IDs/digests and a prune receipt. No automatic age-based prune,
|
|
||||||
no editing of retained metadata, no pruning runs/ under this policy. Until
|
|
||||||
that separately reviewed action exists, keep these private local metadata
|
|
||||||
trees indefinitely; it grants no content access. writing-context objects
|
|
||||||
have a distinct reviewed retention process and are never backed up by release.
|
|
||||||
|
|
||||||
W4b owns the release guard changes, not a follow-up: all eight writing_*
|
|
||||||
tables above join COUNTED in scripts/stack-release.sh:420 and the T46 table
|
|
||||||
classification in packages/cli/tests/stack-release.test.mjs:913. They are
|
|
||||||
non-event writers, not classified as ignorable tables or double-counted as
|
|
||||||
generic events. Jason's existing exact --events N confirmation remains
|
|
||||||
required when the combined post-backup row count is nonzero. A restore plan
|
|
||||||
also compares writing row identities with the proposed source store; equal
|
|
||||||
aggregate counts cannot conceal a dropped revocation replaced by another row.
|
|
||||||
A schema with any unclassified writing_* table refuses restore readiness.
|
|
||||||
|
|
||||||
An **independent host-private fence** lives outside bus/ and every backup:
|
|
||||||
`<dataRoot>/writing-control/restore-fence.json`, directory 0700, regular file
|
|
||||||
0600, no links/mounts/remote/source-copy/rehearse access. Its exact schema is
|
|
||||||
`{version:1,epoch,restoreOperation,droppedRowsDigest,confirmedBusinesses}`.
|
|
||||||
epoch is a host-generated opaque ID; restoreOperation is null before the
|
|
||||||
first restore, otherwise a host-generated opaque operation ID; droppedRowsDigest
|
|
||||||
is SHA-256 of the canonical sorted dropped `(table,id)` list (empty allowed);
|
|
||||||
confirmedBusinesses is a sorted unique array of authenticated business IDs.
|
|
||||||
Only the trusted release controller and existing owner-proof handler write
|
|
||||||
it by durable atomic replacement; agents/testers/request paths cannot.
|
|
||||||
It is not a human-editable readiness setting: verified release readiness is
|
|
||||||
still required, and this file is an additional independent deny fence.
|
|
||||||
|
|
||||||
**First creation:** the compatible release controller durably creates the
|
|
||||||
fence as part of W4b's first schema migration, before committing those empty
|
|
||||||
tables or enabling any handler. It uses a fresh epoch, restoreOperation=null,
|
|
||||||
droppedRowsDigest=SHA-256 of the canonical UTF-8 empty JSON array `[]`, and
|
|
||||||
confirmedBusinesses=[]. Every initial writing row uses that epoch. A normal
|
|
||||||
never-restored store does **not** require editor.restore.confirm: the
|
|
||||||
confirmation gate applies only when restoreOperation is non-null. Initial
|
|
||||||
live grants/shares and verified artifact readiness are still mandatory.
|
|
||||||
|
|
||||||
Initialization is allowed only when the pre-migration schema has no writing_*
|
|
||||||
tables/history and there is no existing fence. If a crash leaves a durable
|
|
||||||
initial fence but the schema transaction uncommitted, migration resumes with
|
|
||||||
that same epoch, not another initial state. If writing tables/history exist
|
|
||||||
and the fence is missing/malformed, fail closed; never repair by creating a
|
|
||||||
new initial fence. Creating an initial fence is not a way around a previous
|
|
||||||
restore or revocation. W4b acceptance exercises both migration crash orders.
|
|
||||||
|
|
||||||
Before **any** store swap/restore (not just one with nonzero counts), the
|
|
||||||
current compatible controller durably creates a fresh epoch, records dropped
|
|
||||||
writing rows and clears confirmedBusinesses. If fencing fails, restore
|
|
||||||
refuses before changing bus/. A crash anywhere keeps O2 denied. Old snapshot
|
|
||||||
rows have old restore_epoch; they cannot authorize even if their grant,
|
|
||||||
policy or share says enabled. Automatic failure recovery and rehearse-driven
|
|
||||||
restore use the same fence. Normal code rollback without store restore
|
|
||||||
keeps the fence and leaves O2 off on incompatible code. A pre-W4b controller
|
|
||||||
is not allowed to restore an O2-enabled data root: the active controller's
|
|
||||||
capability preflight refuses it; operations must use the compatible restore
|
|
||||||
controller even when the target runtime is old.
|
|
||||||
|
|
||||||
After restore, the verified W4b runtime remains unavailable for O2 in every
|
|
||||||
unconfirmed business. New human-only
|
|
||||||
`editor.restore.confirm({expectedEpoch})`, under the business owner's existing
|
|
||||||
trusted human proof, acknowledges that business in the independent fence
|
|
||||||
and returns `{ok:true,result:{business,epoch,confirmed:true}}`. It restores
|
|
||||||
**no old grant/share/policy/conversation**. Fresh current-epoch grants,
|
|
||||||
a fresh dedicated conversation/default policy and fresh human chips must
|
|
||||||
be created explicitly. Past rows may be inspected by an authorized recovery
|
|
||||||
operator as metadata, but never used as current authority or prompt replay.
|
|
||||||
Every read/resolve/cursor/share checks matching restore_epoch and, when
|
|
||||||
restoreOperation is non-null, that business's explicit confirmation; old object bytes remaining on disk are not capabilities.
|
|
||||||
Thus even owner confirmation cannot revive a previously revoked old share.
|
|
||||||
Missing/malformed fence state denies O2. This current-epoch file does not
|
|
||||||
claim to detect a privileged manual rollback of both fence and database;
|
|
||||||
the supported restore protocol never restores the fence from a backup and
|
|
||||||
always rotates it first. A same-uid operator bypassing that protocol is not
|
|
||||||
a boundary this file can prove. --events N approves a
|
|
||||||
store operation only and is never a substitute for this recovery protocol.
|
|
||||||
|
|
||||||
Acceptance seeds a secret in a content object and a share, takes a backup,
|
|
||||||
revokes access/sharing, then restores the backup with explicit row-loss
|
|
||||||
approval: the old share stays refused before and after owner confirmation;
|
|
||||||
a new grant/conversation/chip is needed. Sweep bus.sqlite, WAL/SHM, every
|
|
||||||
backups/stack and bus.post-attempt-* tree, rehearse output and release logs:
|
|
||||||
no secret/title/quote/body marker may appear. Only the explicitly named
|
|
||||||
private writing-context content object may contain it. Verify COUNTED/T46
|
|
||||||
covers each table and simulate failure before/after each fence/store step.
|
|
||||||
|
|
||||||
The XML/ZIP parser safety ceilings and absence-of-remote checks apply to
|
|
||||||
human store ingestion too where needed to prevent path escape and remote
|
|
||||||
replication; a projection-unsupported rich feature alone does not reject a
|
|
||||||
valid human save. Parser refusal codes have a fixed human-readable reason
|
|
||||||
category, never raw XML or a misleading empty context. Fields/hyperlinks/
|
|
||||||
text boxes may make real chapters agent-unreadable in v1; the UI explicitly
|
|
||||||
says this and never claims an empty successful projection.
|
|
||||||
|
|
||||||
Every extractor revision referenced by retained publication history or shares
|
|
||||||
is retained as a verified immutable host artifact. An activation missing one
|
|
||||||
refuses O2 readiness (no silent citation downgrade), including rollback to a
|
|
||||||
W4b-era release that drops a revision. A pre-W4b release can run with O2 wholly
|
|
||||||
off and cannot read those records. Retiring revisions requires a separately
|
|
||||||
reviewed retention/prune operation for all dependent O2 history/shares; not
|
|
||||||
an automatic stack-copy cleanup. Artifact caches are not authorization caches.
|
|
||||||
|
|
||||||
|
Hermes retirement (#423 step5) is a production-opening prerequisite, with old story-write and
|
||||||
|
store-read access removed before any conversion/new-story operation. W7 checks its retirement
|
||||||
|
receipt and host capability preflight; no design seat retires services or accesses Melanie's
|
||||||
|
host. Independent tests use fixtures only. Preserve the existing stack grant/restore behavior;
|
||||||
|
the previous unimplemented W4 private-share restore-fence/table design is withdrawn with M1,
|
||||||
|
not backfilled into legacy rows. Conversion's durable registry is not an authorization token.
|
||||||
## 8. Acceptance matrix and release evidence
|
## 8. Acceptance matrix and release evidence
|
||||||
|
|
||||||
Each row needs a named fixture/test and a mutant or bypass probe in W4b's
|
These are required future fixture gates, not implementation results.
|
||||||
packet. Independent fixtures construct OOXML directly and recompute Unicode
|
|
||||||
slices/digests outside the production extractor. Security checks fail closed;
|
|
||||||
no fixture-only readiness flag may exist in production APIs.
|
|
||||||
|
|
||||||
| ID | Evidence required | Negative control / bypass |
|
| ID | Evidence required | Negative control / bypass |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
@@ -865,117 +593,49 @@ no fixture-only readiness flag may exist in production APIs.
|
|||||||
| A03 | XML ID absent/duplicate and ordinal behavior | missing/mismatched paraId cannot silently choose another node |
|
| A03 | XML ID absent/duplicate and ordinal behavior | missing/mismatched paraId cannot silently choose another node |
|
||||||
| A04 | Emoji, combining characters, tabs, breaks and split runs | UTF-16 offsets, normalization and whitespace collapse fail |
|
| A04 | Emoji, combining characters, tabs, breaks and split runs | UTF-16 offsets, normalization and whitespace collapse fail |
|
||||||
| A05 | Literal split-run wiki forms retained | no path/URL fetch; malformed/cross-paragraph tokens stay text |
|
| A05 | Literal split-run wiki forms retained | no path/URL fetch; malformed/cross-paragraph tokens stay text |
|
||||||
| A06 | Final/original/markup independently verified with moves/deletions | final-only grant cannot read deletion/comment; no document rewrite |
|
| A06 | Final/original/markup independently verified with moves/deletions | default final-body request cannot silently include deletion/comment stories; explicit part/view is separate, no document rewrite |
|
||||||
| A07 | Body/note/endnote/comment exact ownership | orphan/dangling/cross-document references and duplicate IDs refuse |
|
| A07 | Body/note/endnote/comment exact ownership | orphan/dangling/cross-document references and duplicate IDs refuse |
|
||||||
| A08 | Package allowlist, aliases, CRC, XML/ZIP limits | external rel, macro, traversal, symlink, entity, ZIP bomb and timeout refuse |
|
| A08 | Package allowlist, aliases, CRC, XML/ZIP limits | external rel, macro, traversal, symlink, entity, ZIP bomb and timeout refuse |
|
||||||
| A09 | Commit snapshot and publication ordering | next latest after Saved gets new commit; no worktree/draft fallback |
|
| A09 | Commit snapshot and publication ordering | next latest after Saved gets new commit; no worktree/draft fallback |
|
||||||
| A10 | Historical resolve stale label | old quote stays old; removed grant/history refuses without text |
|
| A10 | Historical resolve stale label | old quote stays old; removed grant/history refuses without text |
|
||||||
| A11 | Pagination complete/deterministic and bounded | tampered/foreign/revoked cursor and oversized row refuse |
|
| A11 | Pagination complete/deterministic and bounded | tampered/foreign/revoked cursor and oversized row refuse |
|
||||||
| A12 | Cross-user/business/project/universe denial | guessed IDs, same blob elsewhere and copied document grant nothing |
|
| A12 | Cross-user/business/project/universe denial | foreign project/universe IDs, same blob elsewhere and guessed unpublished objects grant nothing |
|
||||||
| A13 | Visible range chip exact boundaries and default off before gate | no selection/title/path metadata before readiness; draft mapping refused |
|
| A13 | Selection chip points only at committed text; ordinary lookup authority independent | draft mapping refuses; missing chip does not deny an authorized lookup |
|
||||||
| A14 | Every lookup intersects live grant and share | pin, old send, revoked scope and range-to-whole-document escalation fail |
|
| A14 | Normal project/universe/source-scope checks in every thread/room | pin, guessed ID, foreign universe and revoked holder cannot grant access |
|
||||||
| A15 | Whole-document latest share explicit; save rechecked | exact share cannot reveal future edits; persistent policy visible |
|
| A15 | Latest after acknowledged save; explicit historical cite stays immutable | chip/per-send snapshot cannot force stale latest results |
|
||||||
| A16 | Generic file/search/git/export/index paths denied | source copy, symlink, hardlink, alternate object root and new O2 copy probes |
|
| A16 | Host-only store and remote credentials; checked reader routes only | no worker store mount, arbitrary git/engine access or seat remote token |
|
||||||
| A17 | Raw session, fork/resume and transcript boundaries | revoked context cannot replay via raw tool or harness history |
|
| A17 | Existing Case 2 message/transcript policy | no O2-only/raw-session backdoor that skips existing thread/project checks; no false erasure promise |
|
||||||
| A18 | Agent tools exactly read/resolve/flag after gates | native MCP, execute, save, replacement and story comment writes refuse |
|
| A18 | Reader/resolve/flag plus existing Case 2 lookups/supporting writer after gates | native MCP, execute, save, replacement and story comment writes refuse |
|
||||||
| A19 | Existing C2 Markdown reads/line cites unchanged | no DOCX-as-lines conversion or redirect following adoption |
|
| A19 | Unconverted/support Markdown unchanged; converted path returns record and DOCX | no stale archive as chapter or DOCX-as-lines; historical line cite verifies by old commit/blob |
|
||||||
| A20 | Adoption gate before/after readiness and Q36 disposition | absent/revoked server readiness and required notice readiness refuse |
|
| A20 | Conversion/new story gates W4b/W7/PRD/post-10-27/Hermes/owner go | agent start, missing readiness, early release, fixture flag and missing first-real-book go refuse |
|
||||||
| A21 | Human full-feature save remains separate | unsupported projection yields no agent context, never lossy human save |
|
| A21 | Human full-feature save remains separate | unsupported projection yields no agent context, never lossy human save |
|
||||||
| A22 | Scope revocation during extraction | final pre-emission check prevents async stale-authority leak |
|
| A22 | Scope revocation during extraction | final pre-emission check prevents async stale-authority leak |
|
||||||
| A23 | Sibling chapter save | currentCommit/stale/cursor for untouched document remain unchanged |
|
| A23 | Sibling chapter save | currentCommit/stale/cursor for untouched document remain unchanged |
|
||||||
| A24 | Full page and oversized paragraph | end before overflow; first oversized row refuses without text; no unreachable subrange claim |
|
| A24 | Full page and oversized paragraph | end before overflow; first oversized row refuses without text; no unreachable subrange claim |
|
||||||
| A25 | No O2 git remote or release copy | seat Gitea list/fork/clone fails; configured remote/object alternate disables O2; copies exclude stores |
|
| A25 | Every read/write/tool surface uses existing Case 2 isolation | same document ID across business/universe or replayed cursor refuses |
|
||||||
| A26 | Every section 7.4 store/renderer | secret marker absent in each named legacy store, raw session, CLI/Discord/Console view and runs/ |
|
| A26 | Host-only off-host remote and per-save push | unset/local-only/unexpected remote refuses opening; push outage visible, local next lookup still fresh |
|
||||||
| A27 | Pre-W4b rollback reader | new O2 rows never rendered through legacy tables; missing retained extractor disables O2 |
|
| A27 | Conversion restore accounting and durable journal reconciliation | pre-conversion --restore loses counted row but cannot revive Markdown; no lost-event concealment |
|
||||||
| A28 | Dedicated mode vs C2 | mixed attachment/resume/fork denied; unchanged C2 supporting writes/replies fixtures pass |
|
| A28 | Reopened M1 supports same-thread DOCX-read then supporting-note write | any room/project-authorized caller works; no per-document/share token; story/archive write refuses |
|
||||||
| A29 | Two humans/viewer/grant revisions | viewer cannot share; second human cannot join or reuse context; all cursor authority fields checked |
|
| A29 | Readiness is reviewed runtime/extractor plus approved PRD, not caller fields | no request/go/setting can assert release or Hermes retirement |
|
||||||
| A30 | Canonical schemas and complete selections | unknown keys, inconsistent ranges, xmlId null mismatch and noncanonical story IDs refuse |
|
| A30 | Canonical schemas and complete selections | unknown keys, inconsistent ranges, xmlId null mismatch and noncanonical story IDs refuse |
|
||||||
| A31 | Closed leaf/revision table | every leaf/nested rule; mark-only deletion keeps text in final, mark-only insertion keeps text in original; markup mark spans zero-width; Word -1 separator/0 continuation-separator and older 0/1 reserved layouts validate, references to them refuse |
|
| A31 | Closed leaf/revision table | every leaf/nested rule; mark-only deletion keeps text in final, mark-only insertion keeps text in original; markup mark spans zero-width; Word -1 separator/0 continuation-separator and older 0/1 reserved layouts validate, references to them refuse |
|
||||||
| A32 | Initial migration and revocation/restore | initial null-operation fence needs no restore confirmation but no grant is implicit; non-null restore fence needs confirmation and fresh authority; all tables counted/classified; old share stays refused; crash/backup-marker sweeps |
|
| A32 | Existing grant/restore controls and conversion metadata COUNTED | restore cannot revive grant, current Markdown or uncounted conversion event |
|
||||||
|
| A33 | Staging/archive/publish journal and operation readback | crash/sync at every boundary; pinned source until publish; post-push failure pending, not undone |
|
||||||
|
| A34 | Manifest order, typed index/links and format map | next_chapter never archive; draft scope retained; cross-universe/hybrid exclusions and R4/R5/R6 |
|
||||||
|
| A35 | Per-file fidelity, source history, human controls | all constructs/wiki/front matter preserved; no agent conversion; new DOCX has no Markdown precursor |
|
||||||
|
|
||||||
Implementation acceptance includes writing, bus, harness, business, WebUI,
|
Implementation acceptance includes exact schemas/parser fixtures, live project/universe
|
||||||
seat mount/import closure and stack-copy/release fixtures; explicit production
|
revocation probes, same-thread supporting writes, remote denial/failure, counted-event restore
|
||||||
adoption refusal/lift tests; independent parser/policy/tool review; G1 and
|
cases, Hermes gate, pinned-copy/sandbox closure and G1. All skips are named; an unexercised
|
||||||
Sage's allocated schema edge. Evidence must name skips and refuse enablement
|
guard blocks enablement. Old O2-only/private-share acceptance wording is replaced, not claimed
|
||||||
when an acceptance guard was not exercised. W4's review alone lifts nothing.
|
passed. No test, conversion or runtime experiment ran for this rewrite.
|
||||||
|
|
||||||
## 9. Handoff and unresolved decisions
|
## 9. Reopened review and handoff
|
||||||
|
|
||||||
Megavolt reviews this separate document and records a verdict in
|
Fenton reviews this policy rewrite against mos-1368's A17–A41/Q1–Q16 and mos-1372 D1–D9,
|
||||||
`docs/reviews/2026-10-22_q195-docx-citations.md`. Revisions repeat direct
|
including reopened M1 and A19/A20/A28, host-only remote and C5 restoration. Megavolt's old
|
||||||
commit/blob handoff to Megavolt and Sage. Q36 remains with Jason through Mos;
|
APPROVE stays historical at the original blob; no author writes its verdict file. The
|
||||||
no adoption, C2 reader/reply notice change or schema reinterpretation ships
|
locator/projection facts remain source-backed, but the new authority/tool/runtime contract
|
||||||
on this document. W4b's brief must allocate ownership for every surface in
|
requires its own independent approval and the Case 2 PRD approval, not a silent addendum.
|
||||||
A16/A17 and section 7.4 before code: an unowned enforcement path is a blocker, not a deferred security
|
Owner sends both design blobs/commit to Fenton, Mos and Sage. No code, private document,
|
||||||
note. No live files, editor source imports, parser execution or tests were
|
conversion, source build/browser test, queue entry or live change is authorized here.
|
||||||
used to write this design.
|
|
||||||
|
|
||||||
## Round 2 changes against review 08fcb8c1c
|
|
||||||
|
|
||||||
B1: exact selection wrapper, canonical paragraph identity, wiki/anchor schema,
|
|
||||||
chip/share and refusal records; ordinal-primary D25 refinement explicit.
|
|
||||||
B2: closed leaves and nested/paragraph-mark revision rules. B3: per-document
|
|
||||||
publication sequence and sibling-save acceptance. B4/B5: concrete append-only
|
|
||||||
authority, human proof, exact/latest share policy, revision vector and
|
|
||||||
single-human dedicated session lifetime. B6: complete-row paging; oversized
|
|
||||||
paragraph unsupported, no circular subrange API. B7: no remotes/backup push,
|
|
||||||
seat token and copy probes. B8: named native stores, renderers and immutable
|
|
||||||
run evidence, with O2-only storage/adapter readiness. B9: tables/columns,
|
|
||||||
rollback separation and extractor retention. M1: dedicated O2 conversations
|
|
||||||
only; mixed C2 context refused, no C2 requirement change. N1-N7 addressed in
|
|
||||||
canonical manifest, bound-business check, ratio/default wording, UI unavailable
|
|
||||||
reason, release-derived readiness and new A23-A31 acceptance rows. These are
|
|
||||||
proposed definitions, not passing implementation tests. Q36/adoption unchanged.
|
|
||||||
|
|
||||||
## Round 3 changes against review 0d627a2b3
|
|
||||||
|
|
||||||
R2-B1: paragraph-mark revisions preserve all run text; markup has a zero-width
|
|
||||||
mark span, never a fabricated whole-paragraph deletion. Reserved note leaves
|
|
||||||
are allowed only in reserved stories; whole-part structural validation is
|
|
||||||
explicit. A31 covers both mark-only cases and reserved notes.
|
|
||||||
R2-B2: bodies/quoted share payloads move out of SQLite into private content
|
|
||||||
objects; backup/post-attempt metadata paths are named with access/retention
|
|
||||||
rules. Every writing_* table is COUNTED/T46-classified. A non-restored deny
|
|
||||||
fence changes epoch before any store swap; owner confirmation cannot revive
|
|
||||||
old-epoch grants/shares. A32 tests revocation/restore and secret-marker sweeps.
|
|
||||||
R2-N1: agent grant subject means agentInstance. R2-N2: structural leaves have
|
|
||||||
one table. This remains design only; no code, restore, parser run or test.
|
|
||||||
|
|
||||||
## Round 4 changes against review 9fb999abf
|
|
||||||
|
|
||||||
R3-B1: reserved-note classification is by type with any canonical signed ID,
|
|
||||||
not sign; normal notes require nonnegative IDs, and references to reserved
|
|
||||||
notes refuse. A31 covers both actual Word layouts. R3-B2: first migration
|
|
||||||
creates the durable initial epoch before schema commit; null restoreOperation
|
|
||||||
needs no recovery confirmation, a restored epoch does. Missing established
|
|
||||||
fences never reinitialize. A32 covers first enable and post-restore states.
|
|
||||||
R3-N1: business/row/private random nonce are part of each content object and
|
|
||||||
its path, so no cross-business deduplication or guessed-body digest oracle.
|
|
||||||
R3-N2: removed the unsupported claim to detect privileged manual rollback
|
|
||||||
of the fence itself. R3-N3: restore_store anchor corrected to :498.
|
|
||||||
|
|
||||||
### Public Word fixture confirmation (not an extractor test)
|
|
||||||
|
|
||||||
Inspected only public Microsoft-maintained test packages in memory using
|
|
||||||
Python ZIP/XML readers, not the O2 parser or a live/user document. No binary
|
|
||||||
was imported into this repository. Source:
|
|
||||||
[OfficeDev/Open-Xml-PowerTools FootNote.docx](https://github.com/OfficeDev/Open-Xml-PowerTools/blob/a9187c5ec4199106562ec91c5ffd9f355251253b/NewDocxDocuments/FootNote.docx),
|
|
||||||
14,214 bytes; DOCX SHA-256
|
|
||||||
`40e2de78f0f70d8acf3db734df13f107c92986f1a40865cdf9772a8b55ab5e20`.
|
|
||||||
Its app properties identify Microsoft Office Word, version 15.0000.
|
|
||||||
footnotes.xml has separator=-1, continuationSeparator=0, normal note=1;
|
|
||||||
endnotes.xml has separator=-1 and continuationSeparator=0.
|
|
||||||
footnotes.xml SHA-256
|
|
||||||
`1da08d9c0a4a1af2706c035dfb176defd179686f81418134b796d49649e850a0`;
|
|
||||||
endnotes.xml SHA-256
|
|
||||||
`f83e7f1c9f91b44db26b147b22ca615a13488bc6a8084febb392ee00a6ca4f5e`.
|
|
||||||
This confirms the reviewer's -1/0 example in a Word-identified fixture.
|
|
||||||
|
|
||||||
An older independent Microsoft SDK fixture confirms why IDs cannot define
|
|
||||||
the class:
|
|
||||||
[Open-XML-SDK ForTestCase/footnote.docx](https://github.com/dotnet/Open-XML-SDK/blob/431ab05cf160248cc3885a4a766026d4f8243792/test/DocumentFormat.OpenXml.Tests.Assets/assets/TestDataStorage/v2FxTestFiles/ForTestCase/footnote.docx),
|
|
||||||
69,706 bytes, SHA-256
|
|
||||||
`26dc62a5d00e2c3c1df60e0d5bf1cac43b142a090ea595b9ad11ce73e3dab268`.
|
|
||||||
It identifies Microsoft Office Word 12.0000 and uses reserved IDs 0/1 in
|
|
||||||
both parts, with normal footnotes 2/3. No claim is made that the whole
|
|
||||||
packages pass v1's otherwise deliberately restrictive projection rules.
|
|
||||||
Reference in new issue
Block a user