Skip to content

feat: scoped-write interlock (roundtable-consensed, item #5 part 1) - #287

Open
CryptoJones wants to merge 1 commit into
mainfrom
feat/roadmap-janitor-scope
Open

feat: scoped-write interlock (roundtable-consensed, item #5 part 1)#287
CryptoJones wants to merge 1 commit into
mainfrom
feat/roadmap-janitor-scope

Conversation

@CryptoJones

Copy link
Copy Markdown
Owner

Item #5 (part 1) of the 2026-08-27 roadmap consensus: the scope field gains
its second, ratified role — a guard-enforced operational interlock against
accidental cross-project writes. Not a security boundary; deliberately
bypassable; it just turns a fat-fingered out-of-scope write into a loud,
remediable error instead of a silent one.

What it does

  • Denies an out-of-scope write only when BOTH sides declare scope (process via
    OMIND_SCOPE, note via its Scope: field) and they differ. Undeclared
    OMIND_SCOPE fails open; an unscoped note is always writable (unscoped =
    global). Escape hatch: OMIND_SCOPE_MODE=warn downgrades the deny to a
    returned scope_warning. Deny messages spell out remediation.
  • Enforced on the agent-facing create-note / edit-note tools only, so
    mesh/system writes (which call the store directly) are exempt by design — the
    first merge never trips its own guard. create-note gains a scope param;
    edit guards the effective post-edit scope, and an edit that leaves scope
    untouched is still guarded against the note's existing scope.
  • Docs reframed on Note.scope: the interlock role and its bypassability are
    now explicit; "NOT A SECURITY BOUNDARY" survives.

Verification

  • New src/omind/scope_guard.py + tests/test_scope_guard.py (7 unit tests) and
    4 server integration tests. 1,030 tests / ruff / mypy --strict green locally.

Part 2 (scratch tier) and item #3 (omind maintain) follow.

Note: repo CI has a pre-existing red state on main (an mcp dependency-drift
that changes ToolError message text — 5 test_server error-message tests +
Windows flakes). This PR does not touch it; its own new code is green.

Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

🤖 Generated with Claude Code

The scope field gains its second, ratified role: a guard-enforced operational
interlock against accidental cross-project writes. Not a security boundary —
deliberately bypassable — but it turns a fat-fingered out-of-scope write into
a loud, remediable error instead of a silent one.

Per the 2026-08-27 consensus:
- Deny an out-of-scope write only when BOTH sides declare scope (process via
  OMIND_SCOPE, note via its Scope: field) and they differ. Undeclared
  OMIND_SCOPE fails open; an unscoped note is always writable (unscoped =
  global, the retrieval asymmetry). Escape hatch: OMIND_SCOPE_MODE=warn
  downgrades the deny to a returned scope_warning. Deny messages spell out the
  remediation.
- Enforced on the agent-facing create-note / edit-note tools only, so
  mesh/system writes (which call the store directly) are exempt by design —
  the first merge never trips its own guard. create-note gains a scope param;
  edit guards the effective post-edit scope, and an edit that leaves scope
  untouched is still guarded against the note's existing scope.
- Docs reframed on Note.scope: the interlock role and its bypassability are
  now explicit; "NOT A SECURITY BOUNDARY" survives.

The scratch tier (item #5 part 2) and its TTL expiry land with `omind maintain`
(item #3) next. 1,030 tests / ruff / mypy strict green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NbCqLsAJaoeCcyqnTs31Vk
@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8975ea01-7916-476a-a42a-80032c11bf43


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

CryptoJones added a commit that referenced this pull request Aug 28, 2026
Machine-local, auto-expiring scratch notes, marked by a `.scratch.md` filename
suffix (the option chosen for its minimal mesh footprint).

- create-note gains `scratch: bool`; a scratch note is written as
  `<title>.scratch.md`. The suffix IS the mark — no note-body field.
- Still a top-level `*.md`, so search and listings find it like any note.
- Machine-local by default: mesh gitignores `*.scratch.md`, so it is never
  committed or replicated (the "ephemeral + committed to permanent history is
  a contradiction" ruling). Opt-in replicate = create it as a normal note.
- TTL expiry is an `omind maintain` step: scratch notes untouched for 7 days
  (from LAST MODIFICATION — HAL9000's clock refinement) are ARCHIVED, never
  deleted. Reports on a dry run; archives under --apply. Machine-local, so it
  runs outside --sync.

Completes item #5 (the scoped-write interlock is #287). 1,029 tests / ruff /
mypy strict green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NbCqLsAJaoeCcyqnTs31Vk
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant