From 562ca134bf4f5547167e2876227d5d7fb83cef74 Mon Sep 17 00:00:00 2001 From: saagpatel Date: Sun, 19 Jul 2026 23:32:38 -0700 Subject: [PATCH 1/4] chore: map operating-memory-os to Notion --- config/notion-project-map.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/notion-project-map.json b/config/notion-project-map.json index d55b9d4..bc83229 100644 --- a/config/notion-project-map.json +++ b/config/notion-project-map.json @@ -11,6 +11,9 @@ "portfolio-index": { "localProjectId": "378c21f1-caf0-814e-b127-ddbfe578e1e5" }, + "operating-memory-os": { + "localProjectId": "3a3c21f1-caf0-81ec-943f-ed25069652e2" + }, "portfolio-mcp": { "localProjectId": "38dc21f1-caf0-8157-9f5c-d6425a4b32b9" }, From d851fd16c6a43b43056315d58969936bfcc2e0be Mon Sep 17 00:00:00 2001 From: saagpatel Date: Sun, 19 Jul 2026 23:37:35 -0700 Subject: [PATCH 2/4] chore: map operator-scripts to Notion --- config/notion-project-map.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/notion-project-map.json b/config/notion-project-map.json index bc83229..7420cdb 100644 --- a/config/notion-project-map.json +++ b/config/notion-project-map.json @@ -14,6 +14,9 @@ "operating-memory-os": { "localProjectId": "3a3c21f1-caf0-81ec-943f-ed25069652e2" }, + "operator-scripts": { + "localProjectId": "3a3c21f1-caf0-810e-b671-d7cba2618f41" + }, "portfolio-mcp": { "localProjectId": "38dc21f1-caf0-8157-9f5c-d6425a4b32b9" }, From b088c94fc2e9c347b67738c051767db56f61d3bd Mon Sep 17 00:00:00 2001 From: saagpatel Date: Sun, 19 Jul 2026 23:38:52 -0700 Subject: [PATCH 3/4] chore: enroll operator-scripts in project registry --- config/project-registry-overrides.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/config/project-registry-overrides.json b/config/project-registry-overrides.json index 66f495e..7b8acae 100644 --- a/config/project-registry-overrides.json +++ b/config/project-registry-overrides.json @@ -30,6 +30,14 @@ "lifecycle_state": "active", "note": "Local operator control plane (127.0.0.1:46210). Most active project in bridge-db yet absent from auditor portfolio-truth." }, + { + "canonical_key": "operator-scripts", + "display_name": "operator-scripts", + "repo_full_name": "saagpatel/operator-scripts", + "group_key": "operator_infra", + "lifecycle_state": "active", + "note": "Private scheduled-job scripts repository rooted at /Users/d/scripts, outside the default /Users/d/Projects audit scan." + }, { "canonical_key": "supp:SecondBrain", "display_name": "SecondBrain", From 50cbc70f14b668bef20bc75bf4d075a68c71f2e8 Mon Sep 17 00:00:00 2001 From: saagpatel Date: Mon, 20 Jul 2026 00:21:44 -0700 Subject: [PATCH 4/4] fix: resolve configured supplementary identities --- src/operator_os_seam_linter.py | 23 +++++++++++++++++------ tests/test_operator_os_seam_linter.py | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/operator_os_seam_linter.py b/src/operator_os_seam_linter.py index e9c8f70..4894165 100644 --- a/src/operator_os_seam_linter.py +++ b/src/operator_os_seam_linter.py @@ -22,9 +22,9 @@ BRIDGE_CANONICAL_KEY_DISAGREEMENTS, DEFAULT_NOTION_PROJECTION_ONLY_ROWS, DEFAULT_NOTION_TITLE_ALIASES, - DEFAULT_SUPPLEMENTARY, IDENTITY_ALIAS_MAP, IDENTITY_ALIAS_MAP_DEPRECATES_AFTER, + load_overrides_config, normalize, supp_key_for, ) @@ -38,6 +38,9 @@ DEFAULT_NOTION_SNAPSHOT_PATH = Path( "~/.local/share/notion-os/project-snapshot.json" ).expanduser() +DEFAULT_PROJECT_REGISTRY_OVERRIDES_PATH = ( + Path(__file__).resolve().parents[1] / "config" / "project-registry-overrides.json" +) HEX_FRAGMENT_RE = re.compile(r"^[0-9a-fA-F]{3}$") EXPLICIT_UNRESOLVED_IDENTITIES = {"homeadhoc", "unresolved"} @@ -792,14 +795,22 @@ def _build_identity_resolver(truth: dict[str, Any]) -> dict[str, str]: if supp: for value in (identity.get("display_name"), project_key, supp): _add_identity_alias(resolver, value, supp) - # Supplementary registry projects (repo-less operator-OS projects the - # auditor's portfolio-truth does not track, e.g. personal-ops, SecondBrain) - # carry a supp: canonical_key. Seed them so they resolve like any project. - for supp_entry in DEFAULT_SUPPLEMENTARY: + # Supplementary registry projects (operator-OS projects the auditor's + # portfolio-truth does not track) must come from the same operator-owned + # config consumed by the registry generator. Falling back to built-ins + # preserves degraded operation when that config is absent. + _, supplementary, *_ = load_overrides_config( + DEFAULT_PROJECT_REGISTRY_OVERRIDES_PATH + ) + for supp_entry in supplementary: canonical = supp_entry.get("canonical_key") if not isinstance(canonical, str) or not canonical: continue - for value in (supp_entry.get("display_name"), canonical): + for value in ( + supp_entry.get("display_name"), + supp_entry.get("repo_full_name"), + canonical, + ): _add_identity_alias(resolver, value, canonical) # Notion title aliases (e.g. "OrbitForge (staging)" -> OrbitForge): resolve # the alias target to its canonical, then map the drifted title onto it so diff --git a/tests/test_operator_os_seam_linter.py b/tests/test_operator_os_seam_linter.py index 6d0cf15..ac65932 100644 --- a/tests/test_operator_os_seam_linter.py +++ b/tests/test_operator_os_seam_linter.py @@ -456,6 +456,28 @@ def test_identity_resolution_supplementary_project_resolves(tmp_path: Path) -> N assert result.passed, [f.detail for f in result.findings] +def test_identity_resolution_configured_supplementary_repo_resolves( + tmp_path: Path, +) -> None: + # operator-scripts is enrolled only in the operator-owned supplementary + # config, not the built-in fallback. Both bridge identity dialects must + # resolve through the same source used by the registry generator. + truth, markdown = _passing_paths(tmp_path) + _write_identity_truth(truth) + bridge_db = tmp_path / "bridge.db" + _write_bridge_db( + bridge_db, + activity_rows=[ + ("operator-scripts", "saagpatel/operator-scripts"), + ("saagpatel/operator-scripts", "saagpatel/operator-scripts"), + ], + ) + result = lint_operator_os_seams( + truth_path=truth, markdown_paths=markdown, bridge_db_path=bridge_db, now=NOW + ) + assert result.passed, [f.detail for f in result.findings] + + def test_identity_resolution_migration_drift_alias_resolves(tmp_path: Path) -> None: # o2-fable-runpack is OPERANT activity logged under a loose name; the # census-seeded alias map maps it to the operant repo so it resolves.