docs: align O2 chapter conversion and Case 2 access with owner rulings
This commit is contained in:
1 parent
1ac76a4177
commit
8d209016b6
4 files changed
+757
-800
No files matched your search
@@ -5358,3 +5358,9 @@ Gander: after Duckworth-0100 design approval with C1-C5, prepared the two host-s
|
||||
2026-10-22T23:13:27Z | Gyro Q195 O2 fenton-0007 F7/F8 | Named human-only editor.saveGroupPauseMs=2000 and editor.saveGroupMaxMs=15000 with integer/range/cross-field validation and W3a UI/CLI refusal tests. W3b owns production adoption refusal until W4b; isolated fixture conversion remains testable without request-flag bypass. W4b owns adoption module/API tests and reviewed lifting only with committed-reader/citation readiness and, if Q36 approves, the separate notice row PASS. Q36 unresolved stays closed. Static ten-brief, setting-key/bounds, refusal/lift ownership and two-question checks pass. Docs only; no build, browser/worker run, product/queue/live change. Fenton checks F7/F8 on next push.
|
||||
|
||||
2026-10-22T23:13:48Z | Gyro mos-1359 / r3 push guard | D13 records save-group timing as Mos's accepted reading of Q226 F41, not Jason's ruling; both defaults remain human-only settings. Push guard identity gyro/purpose push: exit 0 documented degraded-pass, CANNOT_ASSERT credential-unresolvable; audit gyro-q195-ci-queue-audit.jsonl, no credential fallback or CI-green claim.
|
||||
|
||||
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.
|
||||
@@ -1552,3 +1552,5 @@ are never rewritten or removed; corrections are new entries.
|
||||
2026-10-22T23:03:39Z | Gyro (Codex gpt-6.1-sol, mos-1356) | Q195/Q231/Q233 O2 design rewrite, gyro/editor-o2 from c4f77373f | Canonical queue next gyro: nothing. Ten docs-only briefs; full-feature WordCraft, independent 15-crate/199-package security review, editor-only CSP candidate, instant git DOCX saves and retained Markdown/wiki sources, committed-only DOCX citation gate, no agent story prose. Static structure/source-anchor/scope checks only; no code, build/run, queue or live change. Fenton review requested after push.
|
||||
2026-10-22T23:09:38Z | Gyro (Codex gpt-6.1-sol, fenton-0006) | Q195 O2 design corrections on gyro/editor-o2 | F1 requirement boundary sent to Mos, adoption gated; F2-F6 source-checked docs fixes prepared. Ten briefs and two open owner items checked statically. No implementation, build/browser/worker run, queue or live action; Fenton re-check after push.
|
||||
2026-10-22T23:13:27Z | Gyro (Codex gpt-6.1-sol, fenton-0007) | Q195 O2 r3 F7/F8 | Save-group keys/defaults/validation and W3b refusal/W4b lift ownership explicit. Static docs checks only. Q36 remains open; no implementation or gate lift. Direct Fenton/Mos handoff after push.
|
||||
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;
|
||||
independent reviewer Megavolt. Normative parent: `e36bce352`,
|
||||
`docs/plans/2026-10-21_q195-writing-editor.md`, blob
|
||||
`322ec50f2669cffc0f8256d6beffdaccc4d8dba8`, D12, D24-D26, W4 and W4b.
|
||||
This is a proposed implementation contract, not access enablement or a parser
|
||||
security PASS. Reviewer owns the separate verdict file; the author does not
|
||||
write an approval there.
|
||||
Policy rewrite for Vikunja 571, mos-1366/1367/1368/1372/1375, Q234–Q237.
|
||||
Normative parent: `docs/plans/2026-10-21_q195-writing-editor.md` in the same revision.
|
||||
Original W4: Rocko/Megavolt, #1799, refactor 062646487, blob
|
||||
`2af460ab772f8d204598dc8cb79b3c161f311623`. Gyro writes this assigned revision; Fenton
|
||||
independently reviews it. The reviewer-owned verdict file is untouched.
|
||||
Impact map: brain-redux d183246, `projects/mosaic-mvp/case2-docx-impact-map.md`, stack pin
|
||||
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
|
||||
accepted implementation brief, S0 and its other parent gates. A release must
|
||||
ship extractor, resolver, authorization and sharing together; no partial
|
||||
agent read rollout. Missing server readiness refuses every O2 read, resolve,
|
||||
share and flag. A human setting, pin or request field cannot assert readiness.
|
||||
W5 owns flags, not chapter writes. No agent execute, edit, replace, save,
|
||||
tracked-change or comment-writing operation is introduced.
|
||||
Q235–Q237 P1–P6 and mos-1372 D1/D2 settle the design basis: canon and playground story
|
||||
files become DOCX, retaining universe/book and source scope. Type-folder notes, agent files,
|
||||
instructions, PRDs, character sheets, summaries and supporting documentation stay Markdown.
|
||||
An unmarked-folder story is eligible; the human selects one story file at a time. New
|
||||
stories start directly as DOCX in the human-selected universe/book or playground, without a
|
||||
Markdown precursor, under the same production-opening gate as import.
|
||||
|
||||
Q36 / Vikunja 562 is OPEN. Production Markdown adoption remains closed under
|
||||
mos-1358, independently of whether this design is approved. If Jason approves
|
||||
superseded notices, a separate C2 reader/reply row must implement and pass
|
||||
them before adoption; otherwise Mos records Jason's disposition before any
|
||||
adoption brief proceeds. This document neither implements nor decides notices.
|
||||
The October 27 release stays Markdown. Production import/new-story opening waits for W4b,
|
||||
W7, the post-10-27 release, the approved Case 2 PRD/brief amendment, Hermes retirement
|
||||
(#423 step 5) and configured off-host durability. The first real use on Melanie's books
|
||||
also waits for Jason's scoped go. All starts are human-only; `library.convert` has no role
|
||||
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
|
||||
writer remain unchanged. An authorized old Markdown original is historical
|
||||
source, never the current DOCX or a permission to its later edits. No DOCX
|
||||
paragraph is called a line. Following an adopted source from a C2 read,
|
||||
indexing it as Markdown, changing C2 replies or a synchronized Markdown
|
||||
projection requires a separately approved Case 2 amendment through Mos/Jason.
|
||||
W4b must test old C2 fixtures unchanged alongside the new discriminated DOCX
|
||||
contract. It may migrate only new O2 records, with a named schema edge Sage
|
||||
allocates; it must not reinterpret existing line citations in place.
|
||||
mos-1372 D9 replaces the prior W4 O2-only-conversation, per-document-grant and per-send-share
|
||||
requirements for Case 2 lookups. Agents read converted stories through the normal Case 2
|
||||
lookups in any thread or room under the same live project/universe/source-scope checks as
|
||||
Markdown canon/playground. They can then use existing supporting-Markdown write tools under
|
||||
Q223. The agent never writes a story/DOCX/archive file. D9 is marked as a choice for Jason
|
||||
in PRD 1.17 approval; it is design text, not an already approved role/policy expansion.
|
||||
No code may rely on that changed requirement before the approved PRD and independent review.
|
||||
|
||||
## 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>/`.
|
||||
Business, project and document are opaque IDs resolved through the host's
|
||||
owned manifest, never request paths. Each document has a stable ID and one
|
||||
canonical DOCX path; a rename does not change its identity. A copy/new import
|
||||
gets a new document ID and no inherited grant, share, pin or cache authority.
|
||||
Origin metadata is evidence only. Copying a source does not launder access.
|
||||
The archive is in the human-set source-repository folder, default archive/converted, with
|
||||
converted date, source commit/blob/path and replacement ID in the operation record. It is
|
||||
read-only in the Console. Explicit `archived` scope returns only requested authorized
|
||||
records, always marked and non-canon; default/current queries never opt into it. An old
|
||||
source lookup returns a typed conversion record and routes an authorized DOCX read, never
|
||||
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
|
||||
same commit. It never combines HEAD's manifest with another commit's DOCX.
|
||||
The reader accepts only server-resolved commits reachable from that document's
|
||||
published history; arbitrary git objects and another document's same blob
|
||||
are not selectable. Historical access also requires the document's current
|
||||
live authorization. Removed history, missing blobs or missing extractor
|
||||
revisions refuse; there is no worktree, export or engine-memory fallback.
|
||||
The commit/blob field is a locator, not an authority token.
|
||||
Every conversion runs the pinned extractor before archiving and refuses unsupported output.
|
||||
An independently reviewed importer preserves every wiki token and front-matter key; metadata
|
||||
moves to the canonical manifest (type/name/appears_in/relationships feed the index). Links
|
||||
resolve across Markdown/DOCX through owned aliases, not host paths. A lost link fails the
|
||||
fidelity report. Plain links/front-matter values resolve or raise R4; unresolved chapter
|
||||
embeds must not take the old silent attachment-drop path. Images/.canvas/.base remain attachments.
|
||||
|
||||
The project's sole publication ref is `refs/heads/writing-published`; only
|
||||
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.
|
||||
## 2. Document identity, order and freshness
|
||||
|
||||
The writer's successful commit publishes atomically before Saved. A latest
|
||||
lookup begun after that receipt resolves that published commit, not an old
|
||||
cache entry. A lookup already in progress remains internally on its captured
|
||||
commit. Return the captured version explicitly; never label it latest after
|
||||
observing a newer publish. Recheck live grants immediately before returning
|
||||
content, not just before asynchronous extraction.
|
||||
Host code alone opens `<dataRoot>/writing/<business>/<project>/`. Opaque document IDs resolve
|
||||
through the canonical manifest, never caller paths. Conversion preserves book/chapter identity
|
||||
and scope, binding the original path/name as an alias to the DOCX ID. New stories get a fresh
|
||||
ID and the human-selected universe/book or playground. No format-based canon promotion.
|
||||
The map tells authorized agents format, source scope, owned location and current version;
|
||||
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
|
||||
|
||||
@@ -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.
|
||||
Digest values are lowercase 64-hex SHA-256. Integers are safe nonnegative
|
||||
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:
|
||||
|
||||
@@ -214,10 +227,10 @@ extractor supports them; never guess equivalent namespaces.
|
||||
|
||||
| Class | Exact part names | Story selector | Agent exposure |
|
||||
| --- | --- | --- | --- |
|
||||
| body | word/document.xml | main | final by default, explicit grant |
|
||||
| footnote | word/footnotes.xml | w:footnote/@w:id | own story plus owning document grant |
|
||||
| endnote | word/endnotes.xml | w:endnote/@w:id | own story plus owning document grant |
|
||||
| comment | word/comments.xml | w:comment/@w:id | only explicit comment scope |
|
||||
| body | word/document.xml | main | final by default; existing project/universe access |
|
||||
| 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; same project/universe access as its document |
|
||||
| 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 |
|
||||
| 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 |
|
||||
@@ -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
|
||||
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.
|
||||
Original/markup and comments require separate scopes, so final body access
|
||||
never reveals hidden deletion/comment text. Revision author/date metadata
|
||||
Original/markup and comments are explicit view/part requests under the same project/universe
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
- `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,
|
||||
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
|
||||
scope refuses. A latest cursor continues its captured snapshot with stale
|
||||
metadata if a save intervenes; starting again with null cursor returns the
|
||||
new publication. Cursor is not a capability and grants are rechecked every
|
||||
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;
|
||||
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
|
||||
@@ -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.
|
||||
|
||||
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
|
||||
authorization; `editor-version-unavailable` for authorized missing history or
|
||||
extractor; `editor-citation-invalid` for locator/quote mismatch;
|
||||
`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
|
||||
of those enum strings or editor-policy-conflict/editor-sharing-unsupported
|
||||
(both 409, defined in section 7), and message is fixed server text for that code (no user
|
||||
of those enum strings or editor-policy-conflict (409, stale catalogue/settings revision), and message is fixed server text for that code (no user
|
||||
input). Both missing/foreign and ungranted IDs use the same code/message/status
|
||||
403. Syntax errors before identity lookup use editor-citation-invalid, 400;
|
||||
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
|
||||
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
|
||||
and execution sessions**. Existing C2 threads/sessions cannot be converted,
|
||||
attached to O2 context or resumed/forked into O2 mode; new IDs and a fresh
|
||||
empty context are mandatory. There is no mixed-thread turn. The UI offers
|
||||
"Open dedicated writing conversation", never silently changes an existing
|
||||
chat's permissions. Existing C2-02 supporting-doc writes and C2-06 replies
|
||||
retain their semantics. The narrowing below belongs only to this explicitly
|
||||
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.
|
||||
Keep `library_find`, `library_get`, `library_search`, `library_manuscript` and the universe
|
||||
lookup. Host adapters join Markdown metadata/read results and the committed DOCX extractor
|
||||
into one typed, scope-filtered index; only current identities enter normal lookups. A request
|
||||
on a converted alias returns its conversion record and the authorized DOCX result. Every
|
||||
answer names format, store/owned ID and captured commit. No loss of chapter search/manuscript
|
||||
or supporting-doc workflow is accepted. Same project/universe/source-scope rules apply in
|
||||
all threads/rooms; archive/draft scope never becomes canon because its format is DOCX.
|
||||
|
||||
Authorization principal is a tuple, not a seat's display name:
|
||||
`{business,human,agentInstance,conversation,executionSession}`. human is the
|
||||
stable authenticated identity that owns the O2 conversation; agentInstance
|
||||
and executionSession come from its bound broker run. The request cannot
|
||||
supply/replace them. All human readers and all agent lookups require live
|
||||
R5 project/universe access plus the O2 grant below; role files grant the
|
||||
operation only. The business owner is not an implicit reader of someone
|
||||
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.
|
||||
DOCX pages use paragraph locators and opaque cursors, not invented line equivalents.
|
||||
Retain section 6's 64-KiB/1..100 paragraph bounds (default20); human reply limits still apply.
|
||||
A manuscript cursor binds ordered-manifest commit, the selected document publication vector,
|
||||
principal/request/scope revisions and expiry. Resume only that snapshot with current access;
|
||||
changed/foreign cursor refuses. next_chapter uses the next visible current manifest ID,
|
||||
never an archive or a guessed sort of DOCX names. Index/cache keys include local publication
|
||||
and extractor revisions; no minute-old Markdown refresh window is copied to DOCX.
|
||||
|
||||
O2 scopes live in the new append-only bus table writing_access_events, not
|
||||
access.json or role-file wildcard changes. Proposed human-only verb
|
||||
`editor.access.set({project,document,subject,scope,expectedRevision})` takes
|
||||
subject exactly `{kind:"human"|"agent",id}`; agent id is the business's
|
||||
bus agent **instance ID**, equal to principal.agentInstance, never a role
|
||||
definition ID or a seat display name. scope is exactly
|
||||
`{enabled,parts,views,history,mayShare}`. parts is a sorted unique nonempty
|
||||
subset of body/footnote/endnote/comment (all stories within the selected
|
||||
class); views is a sorted unique nonempty subset final/original/markup;
|
||||
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.
|
||||
C2-06's checked cite union preserves legacy `{path,commit,lines,quote,as?}` for Markdown and
|
||||
adds `{kind:"docx",locator,as?}` where locator is section3's exact range/selection. Never infer
|
||||
a cite kind from a .docx suffix or parse DOCX as lines. The host checks project/universe,
|
||||
source canon/playground/archive status, fetched provenance, quote and commit before message
|
||||
storage. requireCitation and as:canon apply to both; historical converted/archived sources
|
||||
cannot assert current canon. The host reads Mosaic-Agent trailers from the correct source
|
||||
repository or writing-store publication, never trusts an agent author field. Console and
|
||||
the shared reply renderer show format, locator/lines, version, staleness and converted state.
|
||||
C2-18 Discord remains a separate ruled delivery task, not enabled by a shared renderer.
|
||||
|
||||
Only the existing business-owner human proof may write these policy grants,
|
||||
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.
|
||||
## 7. Existing Case 2 authority, remote durability and restore
|
||||
|
||||
Each access decision records an authority vector exactly
|
||||
`{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.1 Access and supporting writes (reopened M1)
|
||||
|
||||
### 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
|
||||
second human joins it in v1: a thread-share attempt refuses
|
||||
editor-sharing-unsupported (409), rather than borrowing the sender's grants
|
||||
for someone else. A second human starts a separate O2 conversation, supplies
|
||||
their own grant/share and gets no previous content. This is a new O2 mode,
|
||||
not a restriction on existing C2 sharing. Human and agent must still have
|
||||
matching business/project/universe rights. Read-only previews cannot send.
|
||||
The existing `library_doc_write`/`library_doc_delete` still require library.write plus the
|
||||
live supporting-repo Gitea grant and supportingPath before git. They operate only on human-
|
||||
marked supporting Markdown, with the existing size/base-CAS/seat-author/push/notice/revert
|
||||
rules. An agent can read a DOCX story and update its character sheet in the same authorized
|
||||
thread. There is no agent write to DOCX, original story, archive or conversion manifest.
|
||||
The archive prefix wins over supporting globs; conflicts refuse mapping. Format/status/type
|
||||
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
|
||||
available only to that authenticated owner with current write access over
|
||||
the same trusted write transports. mode is off/visible-chip-per-send/
|
||||
conversation-current. It atomically appends writing_policy_events and returns
|
||||
`{ok:true,result:{id,revision,previousRevision,mode}}`. Default is the explicit
|
||||
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.
|
||||
The cursor authority revision is the server's current project grant, universe/mapping/scope
|
||||
revision and format-publication generation for the bound caller/session. It contains no
|
||||
sharing human or writing_access_events/writing_shares sequence. Recheck before every page,
|
||||
resolution, index hit and message insertion. Scope revocation and format changes invalidate
|
||||
cached authorization; metadata for missing/foreign IDs uses the same refusal as before.
|
||||
|
||||
In visible-chip-per-send the human sends exactly
|
||||
`{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:
|
||||
### 7.2 Selection convenience and ordinary messages
|
||||
|
||||
- `{kind:"range",document,baseCommit,selection}` where selection is one
|
||||
docx-range/docx-selection locator, with its business/project/document/
|
||||
commit equal to the server-owned conversation/document and baseCommit.
|
||||
- `{kind:"document",document,baseCommit,parts,views,history}` selecting a
|
||||
whole-document **exact publication**, with explicit part/view lists and
|
||||
history boolean constrained by both grants.
|
||||
Keep Q233's human-only setting, default a visible removable chip on each send. A chip may
|
||||
attach only a verified committed locator/version, never unsaved selection text. It helps the
|
||||
writer point at a passage; it neither grants nor limits the agent's ordinary project/universe
|
||||
lookup rights and does not freeze a later latest lookup to that older commit. The sent cite
|
||||
remains immutable historical evidence. Multi-human/thread/room behavior follows existing Case 2
|
||||
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
|
||||
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.
|
||||
### 7.3 Host-only off-host remote (replaces the ban)
|
||||
|
||||
A range share permits only editor_resolve_citation for that exact locator
|
||||
(or a range wholly contained within it with newly verified quote/digest).
|
||||
It always refuses editor_read_committed, since rows would expose surrounding
|
||||
text. A document exact share allows paging only its named publication,
|
||||
parts/views; it never grants future saves. No implicit body-to-note/comment
|
||||
or final-to-markup expansion occurs.
|
||||
`editor.remoteURL` is a human-only setting, default unset. No same-host bare/filesystem/loopback
|
||||
remote is the default or qualifies as off-host durability. The human selects an off-stack-host
|
||||
private destination (for example private Gitea) and separately configures host-only auth.
|
||||
Only the host process pushes. No seat token can list/fetch/clone/fork/push the writing repo,
|
||||
no seat gets its credential, and no raw Gitea grant or store mount is created. Validate the
|
||||
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
|
||||
indicator and a required whole-document chip. The same chip fields bind
|
||||
baseCommit and scope, but the share record has versionMode=latest: baseCommit
|
||||
is the acknowledged publication at issuance, not a future-version ceiling.
|
||||
The next authorized latest lookup after Saved follows currentCommit within
|
||||
the granted part/view/history bounds. This exception to exact-version sharing
|
||||
exists only in this explicit mode. Range chips are refused in this mode,
|
||||
not silently upgraded. Pins and earlier exact shares never become latest.
|
||||
Every writing-store commit pushes there. Agents read the local publication immediately;
|
||||
receipts/UI distinguish local commit and remote pending/failed/synced. Missing remote blocks
|
||||
production opening. Before source archive push, the staged DOCX must have remote acknowledgment.
|
||||
A failed later push keeps local commits, queues bounded host retry/readback and shows failure;
|
||||
it never rolls back the local story. Source archives push through their separate human
|
||||
library writer. The configured retry deadline is human-only (default30s, 1s..300s).
|
||||
Remote/provisioning changes require the normal owner authority, never this design execution.
|
||||
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
|
||||
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.4 Conversion events, rollback --restore and irreversible recovery
|
||||
|
||||
### 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
|
||||
`{version,id,restoreEpoch,business,project,document,conversation,executionSession,message,
|
||||
human,agentInstance,mode,versionMode,baseCommit,blob,extractor,scope,selection,
|
||||
authority,policyRevision,issuedAt}`. version=1; IDs use section 3 grammar;
|
||||
mode is the policy at issuance; versionMode is exact/latest; baseCommit/blob
|
||||
are the acknowledged snapshot and extractor is its exact pinned revision.
|
||||
scope is `{parts,views,history}` as above; selection is the verified locator
|
||||
for a range, otherwise null. authority is the complete revision vector at
|
||||
issuance; its share field equals this row's seq (assigned atomically).
|
||||
restoreEpoch must equal authority.restoreEpoch and the live independent
|
||||
fence. issuedAt is canonical UTC millisecond ISO timestamp. policyRevision equals
|
||||
authority.sharingPolicy. message names a new writing_messages row, not a C2
|
||||
message. A unique `(conversation,message,document)` constraint and operation
|
||||
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.
|
||||
Three recovery cases are required: (1) crash after durable DOCX staging but before archive
|
||||
push, (2) crash after archive push before publication, and (3) rollback --restore from a
|
||||
pre-conversion bus backup while archive commits and O2 documents remain. The source is pinned
|
||||
until final publication in cases1/2; after archive push state is visibly pending, never
|
||||
'original untouched'. Case3 drops conversion rows only through the counted/approved restore
|
||||
path. The durable host conversion journal/format registry is not restored from that older bus
|
||||
backup. A compatible controller compares journal, both git histories, remote acknowledgment
|
||||
and restored metadata before lookups/writes resume; it reconstructs missing metadata through
|
||||
new recovery events without reviving Markdown or any old access grant. If reconciliation
|
||||
cannot prove a single current identity/version, refuse that project's lookups and surface the
|
||||
pending operation to the human. Do not replay chapter text into an old index or hide event loss.
|
||||
Incompatible old binaries cannot activate converted projects through the supported controller;
|
||||
raw privileged rollback tampering is outside the guarantee. Never rewrite git/run history.
|
||||
|
||||
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
|
||||
|
||||
Each row needs a named fixture/test and a mutant or bypass probe in W4b's
|
||||
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.
|
||||
These are required future fixture gates, not implementation results.
|
||||
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| A12 | Cross-user/business/project/universe denial | guessed IDs, same blob elsewhere and copied document grant nothing |
|
||||
| A13 | Visible range chip exact boundaries and default off before gate | no selection/title/path metadata before readiness; draft mapping refused |
|
||||
| A14 | Every lookup intersects live grant and share | pin, old send, revoked scope and range-to-whole-document escalation fail |
|
||||
| A15 | Whole-document latest share explicit; save rechecked | exact share cannot reveal future edits; persistent policy visible |
|
||||
| A16 | Generic file/search/git/export/index paths denied | source copy, symlink, hardlink, alternate object root and new O2 copy probes |
|
||||
| A17 | Raw session, fork/resume and transcript boundaries | revoked context cannot replay via raw tool or harness history |
|
||||
| A18 | Agent tools exactly read/resolve/flag 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 |
|
||||
| A20 | Adoption gate before/after readiness and Q36 disposition | absent/revoked server readiness and required notice readiness refuse |
|
||||
| A12 | Cross-user/business/project/universe denial | foreign project/universe IDs, same blob elsewhere and guessed unpublished objects grant nothing |
|
||||
| A13 | Selection chip points only at committed text; ordinary lookup authority independent | draft mapping refuses; missing chip does not deny an authorized lookup |
|
||||
| A14 | Normal project/universe/source-scope checks in every thread/room | pin, guessed ID, foreign universe and revoked holder cannot grant access |
|
||||
| A15 | Latest after acknowledged save; explicit historical cite stays immutable | chip/per-send snapshot cannot force stale latest results |
|
||||
| A16 | Host-only store and remote credentials; checked reader routes only | no worker store mount, arbitrary git/engine access or seat remote token |
|
||||
| A17 | Existing Case 2 message/transcript policy | no O2-only/raw-session backdoor that skips existing thread/project checks; no false erasure promise |
|
||||
| A18 | Reader/resolve/flag plus existing Case 2 lookups/supporting writer after gates | native MCP, execute, save, replacement and story comment writes refuse |
|
||||
| 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 | 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| A26 | Every section 7.4 store/renderer | secret marker absent in each named legacy store, raw session, CLI/Discord/Console view and runs/ |
|
||||
| A27 | Pre-W4b rollback reader | new O2 rows never rendered through legacy tables; missing retained extractor disables O2 |
|
||||
| A28 | Dedicated mode vs C2 | mixed attachment/resume/fork denied; unchanged C2 supporting writes/replies fixtures pass |
|
||||
| A29 | Two humans/viewer/grant revisions | viewer cannot share; second human cannot join or reuse context; all cursor authority fields checked |
|
||||
| A25 | Every read/write/tool surface uses existing Case 2 isolation | same document ID across business/universe or replayed cursor refuses |
|
||||
| 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 | Conversion restore accounting and durable journal reconciliation | pre-conversion --restore loses counted row but cannot revive Markdown; no lost-event concealment |
|
||||
| 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 | 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 |
|
||||
| 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,
|
||||
seat mount/import closure and stack-copy/release fixtures; explicit production
|
||||
adoption refusal/lift tests; independent parser/policy/tool review; G1 and
|
||||
Sage's allocated schema edge. Evidence must name skips and refuse enablement
|
||||
when an acceptance guard was not exercised. W4's review alone lifts nothing.
|
||||
Implementation acceptance includes exact schemas/parser fixtures, live project/universe
|
||||
revocation probes, same-thread supporting writes, remote denial/failure, counted-event restore
|
||||
cases, Hermes gate, pinned-copy/sandbox closure and G1. All skips are named; an unexercised
|
||||
guard blocks enablement. Old O2-only/private-share acceptance wording is replaced, not claimed
|
||||
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
|
||||
`docs/reviews/2026-10-22_q195-docx-citations.md`. Revisions repeat direct
|
||||
commit/blob handoff to Megavolt and Sage. Q36 remains with Jason through Mos;
|
||||
no adoption, C2 reader/reply notice change or schema reinterpretation ships
|
||||
on this document. W4b's brief must allocate ownership for every surface in
|
||||
A16/A17 and section 7.4 before code: an unowned enforcement path is a blocker, not a deferred security
|
||||
note. No live files, editor source imports, parser execution or tests were
|
||||
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.
|
||||
Fenton reviews this policy rewrite against mos-1368's A17–A41/Q1–Q16 and mos-1372 D1–D9,
|
||||
including reopened M1 and A19/A20/A28, host-only remote and C5 restoration. Megavolt's old
|
||||
APPROVE stays historical at the original blob; no author writes its verdict file. The
|
||||
locator/projection facts remain source-backed, but the new authority/tool/runtime contract
|
||||
requires its own independent approval and the Case 2 PRD approval, not a silent addendum.
|
||||
Owner sends both design blobs/commit to Fenton, Mos and Sage. No code, private document,
|
||||
conversion, source build/browser test, queue entry or live change is authorized here.
|
||||
Reference in new issue
Block a user