Phase 5 enterprise track (code GO, release held on owner gates)#313
Closed
samrusani wants to merge 1 commit into
Closed
Phase 5 enterprise track (code GO, release held on owner gates)#313samrusani wants to merge 1 commit into
samrusani wants to merge 1 commit into
Conversation
Team-built, independently reviewed, and independently re-verified by release engineering. Integrates the enterprise-track work on top of the merged security fixes (PRs #310, #311, #312): a short-lived, origin-bound, one-time browser-clip capability (raw value never stored, atomic single-use consume, no cross-origin replay; migration 0094); Stage A security threat model, authorization and input-validation sweeps, and secret-handling and dependency-posture evidence; executed backup, restore, portable export/import, v0.12-to-current upgrade, and disaster-recovery evidence on SQLite and PostgreSQL 16; a hardened review dashboard with an authenticated /vnext operator path; and a single-tenant deployment contract with validation tooling. Versions remain 0.13.1. This commit runs committed-SHA CI only; it does not cut 0.14.0, tag, or publish. Phase 5 completion stays NO-GO pending two owner gates: the 5.1.c independent external security review and the 5.4 real-host deployment receipt. Stage A is not Stage B; the checked-in deployment contract is not real-host evidence. Verified by release engineering: carrier receipt recomputed from live bytes (4cf7e08b, 20,845 bytes, exact match); 4,030 unit tests pass; control-doc truth and release_check pass at 0.13.1; the browser-clip security properties confirmed at the code level and the origin-binding test proven non-vacuous by mutation. Alice-Carrier-Receipt-SHA256: 4cf7e08b6faddd681daf2217fe3c7184746be4ca34cf7b71098637ce7eb2ed34 Alice-Build-Report-SHA256: af85f5497fb1e0f23889233632a4fe0d4bb771f18a0b9637cedde2e9bb95c9e5 Alice-Review-Report-SHA256: 138fdfca00c2a4652e800964227a185e43b8ea3fbf628ba01bdc5e062f78ea0a
| }); | ||
|
|
||
| it("uses only an origin-bound one-time capability in visited-page code", () => { | ||
| expect(bookmarklet.startsWith("javascript:")).toBe(true); |
| const serializedDomain = JSON.stringify(domain); | ||
| const serializedSensitivity = JSON.stringify(sensitivity); | ||
|
|
||
| return `javascript:(async()=>{try{const endpoint=${serializedEndpoint};const user_id=${serializedUserId};const capture_capability=${serializedCapability};const expected_origin=${serializedOrigin};if(location.origin!==expected_origin){alert("This Alice clip is bound to "+expected_origin+". Prepare a new clip for this page.");return;}const user_note=prompt("Optional note","");const selection=window.getSelection()?.toString()??"";const body={user_id,url:location.href,title:document.title,selected_text:selection||null,page_text:selection?null:(document.body?.innerText??"").slice(0,20000),user_note:user_note||null,capture_capability,domain:${serializedDomain},sensitivity:${serializedSensitivity}};await fetch(endpoint,{method:"POST",mode:"no-cors",body:JSON.stringify(body)});alert("Alice clip request submitted. Verify it in the Alice Inbox.")}catch{alert("Alice clip request failed before submission.")}})();`; |
| const serializedDomain = JSON.stringify(domain); | ||
| const serializedSensitivity = JSON.stringify(sensitivity); | ||
|
|
||
| return `javascript:(async()=>{try{const endpoint=${serializedEndpoint};const user_id=${serializedUserId};const capture_capability=${serializedCapability};const expected_origin=${serializedOrigin};if(location.origin!==expected_origin){alert("This Alice clip is bound to "+expected_origin+". Prepare a new clip for this page.");return;}const user_note=prompt("Optional note","");const selection=window.getSelection()?.toString()??"";const body={user_id,url:location.href,title:document.title,selected_text:selection||null,page_text:selection?null:(document.body?.innerText??"").slice(0,20000),user_note:user_note||null,capture_capability,domain:${serializedDomain},sensitivity:${serializedSensitivity}};await fetch(endpoint,{method:"POST",mode:"no-cors",body:JSON.stringify(body)});alert("Alice clip request submitted. Verify it in the Alice Inbox.")}catch{alert("Alice clip request failed before submission.")}})();`; |
| const serializedDomain = JSON.stringify(domain); | ||
| const serializedSensitivity = JSON.stringify(sensitivity); | ||
|
|
||
| return `javascript:(async()=>{try{const endpoint=${serializedEndpoint};const user_id=${serializedUserId};const capture_capability=${serializedCapability};const expected_origin=${serializedOrigin};if(location.origin!==expected_origin){alert("This Alice clip is bound to "+expected_origin+". Prepare a new clip for this page.");return;}const user_note=prompt("Optional note","");const selection=window.getSelection()?.toString()??"";const body={user_id,url:location.href,title:document.title,selected_text:selection||null,page_text:selection?null:(document.body?.innerText??"").slice(0,20000),user_note:user_note||null,capture_capability,domain:${serializedDomain},sensitivity:${serializedSensitivity}};await fetch(endpoint,{method:"POST",mode:"no-cors",body:JSON.stringify(body)});alert("Alice clip request submitted. Verify it in the Alice Inbox.")}catch{alert("Alice clip request failed before submission.")}})();`; |
| const serializedDomain = JSON.stringify(domain); | ||
| const serializedSensitivity = JSON.stringify(sensitivity); | ||
|
|
||
| return `javascript:(async()=>{try{const endpoint=${serializedEndpoint};const user_id=${serializedUserId};const capture_capability=${serializedCapability};const expected_origin=${serializedOrigin};if(location.origin!==expected_origin){alert("This Alice clip is bound to "+expected_origin+". Prepare a new clip for this page.");return;}const user_note=prompt("Optional note","");const selection=window.getSelection()?.toString()??"";const body={user_id,url:location.href,title:document.title,selected_text:selection||null,page_text:selection?null:(document.body?.innerText??"").slice(0,20000),user_note:user_note||null,capture_capability,domain:${serializedDomain},sensitivity:${serializedSensitivity}};await fetch(endpoint,{method:"POST",mode:"no-cors",body:JSON.stringify(body)});alert("Alice clip request submitted. Verify it in the Alice Inbox.")}catch{alert("Alice clip request failed before submission.")}})();`; |
| const serializedDomain = JSON.stringify(domain); | ||
| const serializedSensitivity = JSON.stringify(sensitivity); | ||
|
|
||
| return `javascript:(async()=>{try{const endpoint=${serializedEndpoint};const user_id=${serializedUserId};const capture_capability=${serializedCapability};const expected_origin=${serializedOrigin};if(location.origin!==expected_origin){alert("This Alice clip is bound to "+expected_origin+". Prepare a new clip for this page.");return;}const user_note=prompt("Optional note","");const selection=window.getSelection()?.toString()??"";const body={user_id,url:location.href,title:document.title,selected_text:selection||null,page_text:selection?null:(document.body?.innerText??"").slice(0,20000),user_note:user_note||null,capture_capability,domain:${serializedDomain},sensitivity:${serializedSensitivity}};await fetch(endpoint,{method:"POST",mode:"no-cors",body:JSON.stringify(body)});alert("Alice clip request submitted. Verify it in the Alice Inbox.")}catch{alert("Alice clip request failed before submission.")}})();`; |
| const serializedDomain = JSON.stringify(domain); | ||
| const serializedSensitivity = JSON.stringify(sensitivity); | ||
|
|
||
| return `javascript:(async()=>{try{const endpoint=${serializedEndpoint};const user_id=${serializedUserId};const capture_capability=${serializedCapability};const expected_origin=${serializedOrigin};if(location.origin!==expected_origin){alert("This Alice clip is bound to "+expected_origin+". Prepare a new clip for this page.");return;}const user_note=prompt("Optional note","");const selection=window.getSelection()?.toString()??"";const body={user_id,url:location.href,title:document.title,selected_text:selection||null,page_text:selection?null:(document.body?.innerText??"").slice(0,20000),user_note:user_note||null,capture_capability,domain:${serializedDomain},sensitivity:${serializedSensitivity}};await fetch(endpoint,{method:"POST",mode:"no-cors",body:JSON.stringify(body)});alert("Alice clip request submitted. Verify it in the Alice Inbox.")}catch{alert("Alice clip request failed before submission.")}})();`; |
|
|
||
| def validate_caddyfile(text: str) -> None: | ||
| normalized = "\n".join(line.split("#", 1)[0].rstrip() for line in text.splitlines()) | ||
| _require("alice.example.com" in normalized, "caddy_public_host_missing") |
Owner
Author
|
Returning the carrier to the team. Committed-SHA CI on e8d2018 surfaced 6 issues (5 CI-portability/tooling: shallow-clone guard, missing tags for the ops upgrade drill, hardcoded venv path in migrate.sh, and a gitleaks false positive on an example env; plus 1 real browser-clip transport test failure at navigation.spec.ts:114). The carrier passed the local matrix only because the build env had full git history, tags, and a .venv. Fix and re-deliver a fresh uncommitted carrier with a new receipt; this exact 4cf7e08b carrier is not shippable. Full diagnosis handed off separately. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Team-built Phase 5 enterprise-track carrier, independently reviewed and independently re-verified by release engineering. Carrier receipt
4cf7e08b…recomputed from live bytes (exact match); 4,030 unit tests pass locally; the browser-clip capability's security properties were confirmed at the code level and its origin-binding test proven non-vacuous by mutation.This PR runs committed-SHA CI only. It is a draft and holds the release. Versions remain 0.13.1. Phase 5 completion is NO-GO pending two owner gates: the 5.1.c independent external security review and the 5.4 real-host deployment receipt. No 0.14.0 cut, tag, or publish happens until those close and this CI is green.
Builds on the merged security fixes (#310, #311, #312). Delivers: a short-lived, origin-bound, one-time browser-clip capability (raw value never stored, atomic single-use consume, migration 0094); Stage A security evidence; executed backup/restore/upgrade/DR evidence on SQLite and PostgreSQL 16; a hardened review dashboard; and a single-tenant deployment contract with validation tooling.
Upgrade Overview
Protected Areas
Compatibility Impact
Additive only. Existing routes, tools, and stored data are unaffected. The new browser-clip capability is a new, authenticated, origin-scoped feature; the previous reusable-token clipper behavior is replaced by the one-time capability (the fix for the security-review finding).
Migration / Rollout
One additive Alembic migration (0094) creating the browser_clip_capabilities table; the SQLite bootstrap gains the same table. No existing data is migrated or destroyed.
Operator Action
None for existing deployments. The single-tenant deployment guide and ops-evidence tooling are new documentation and scripts; using them is optional and covered by the 5.4 owner gate.
Validation
Carrier receipt recomputed to 4cf7e08b (exact); 4,030 unit tests pass; control-doc truth and release_check pass at 0.13.1; browser-clip security verified and its tests proven non-vacuous. Integration, web, browser, and ops drills run on this committed SHA via CI.
Rollback
Revert the carrier commit and run the 0094 downgrade (drops the browser_clip_capabilities table). No existing data is affected by rollback.