fix(portfolio-truth): reconcile operator attention#192
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 01e697cc43
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # GPT_RAG removed from this cohort by operator ruling 2026-07-17: the tribunal | ||
| # found its live-driver claim evidentially false (the JSON trace artifacts its | ||
| # README promises exist nowhere in the tree), so it is dormant, not manual-only. | ||
| tier_zero = { |
There was a problem hiding this comment.
Make the Tier 0 attention assertion exclusive
This test only proves that the eight named repos are active; it does not fail when other catalog rows can still enter default attention. In this same catalog, rag-knowledge-base and saagpatel/operant remain active + maintain + infrastructure, and _attention_state_for classifies active/recent projects with that contract as active-infra, so a fresh checkout of either still inflates default attention beyond the operator-confirmed eight. Please assert the eligible set is exactly tier_zero or demote the extra contracts.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 9b20cee. rag-knowledge-base is now manual-only, and the regression normalizes the operant-public / saagpatel/operant lookup aliases before asserting the eligible logical set is exactly the eight Tier 0 projects.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9b20ceec6c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| and entry["operating_path"] in {"maintain", "finish"} | ||
| and entry["category"] in {"infrastructure", "commercial"} | ||
| } | ||
| assert eligible_catalog_keys == {name.lower() for name in tier_zero} |
There was a problem hiding this comment.
Update the security cohort limit for eight Tier 0 repos
This new assertion makes the reconciled default-attention catalog set exactly eight projects, but the GitHub security collector still fails closed unless it sees 16 default-attention repos: derive_default_attention_cohort defaults expected_count to 16 and raises on any other size, and the CLI default remains --expected-cohort-count 16 (src/github_security_coverage.py:151-175, src/github_security_coverage.py:1333). After regenerating portfolio truth from this catalog, running the normal security coverage command without an override will stop before writing a receipt with default-attention cohort size changed, leaving the new Tier 0 cohort without the bounded GHAS coverage artifact.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cce9c9e814
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "top_level_dir": "supplementary", | ||
| "group_entry": {}, | ||
| "has_git": False, | ||
| "repo_full_name": "", |
There was a problem hiding this comment.
Exclude repo-less projects from GitHub cohort
When the catalog contains personal-ops, this synthesized supplementary project is emitted as active-infra while repo_full_name is blank. src.github_security_coverage.derive_default_attention_cohort() includes every active-product/active-infra/decision-needed project and validates identity.repo_full_name, so refreshing the GitHub security receipt against regenerated truth now fail-closes with invalid canonical repository name: '' before any receipt can be written. Please keep repo-less supplementary identities out of the GitHub security cohort or give them a separate non-GitHub security path.
Useful? React with 👍 / 👎.
| if lifecycle_state == "active" and operating_path == "maintain": | ||
| if category == "infrastructure": | ||
| return "active-infra" | ||
| if category == "commercial": | ||
| return "active-product" |
There was a problem hiding this comment.
Reconcile the security cohort size with Tier 0
This attention reconciliation intentionally moves the generated default-attention set to ten logical projects, but the GitHub security receipt producer still defaults to expected_count=16 in src/github_security_coverage.py. In any default receipt refresh after regenerating portfolio truth, the collector will fail with default-attention cohort size changed unless the operator remembers to pass an override, leaving the validated security overlay stale despite the new catalog being canonical.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b8fa89bb1b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "top_level_dir": "supplementary", | ||
| "group_entry": {}, | ||
| "has_git": False, | ||
| "repo_full_name": "", |
There was a problem hiding this comment.
Don't count repo-less rows in the GHAS cohort
When this cataloged supplementary row is promoted with an empty repo_full_name (currently personal-ops), _build_truth_project still marks default-attention projects without a receipt as security.cohort_member=True. That makes portfolio truth count this repo-less active-infra identity in the GitHub security cohort even though derive_default_attention_cohort skips supp: rows and validates only the 9 repo-backed repositories, so coverage summaries/security gates will show a permanently missing GitHub scan for a project that cannot be queried. Gate the fallback cohort marking on a real repo full name or explicitly keep supplementary rows outside the GitHub cohort.
Useful? React with 👍 / 👎.
| validate_security_coverage_receipt( | ||
| prior_receipt, | ||
| max_age_hours=24 * 365, | ||
| expected_cohort_count=expected_cohort_count, |
There was a problem hiding this comment.
Ignore old prior receipts after cohort changes
When an operator already has a receipt from the previous 16-repo cohort and runs the default collector after this policy contraction to 9 repos, main() loads that file as prior_receipt and this validation now checks it against expected_cohort_count=9. The old receipt fails with cohort count contract mismatch before any GitHub requests are attempted, so the tool cannot write the new 9-repo receipt unless the user manually deletes the prior file. Since the prior receipt is only used for conditional requests/eligibility hints, a mismatched prior should be ignored or validated against its embedded cohort instead of blocking refresh.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ea946c603
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "project_path": None, | ||
| "path": canonical_key, | ||
| "top_level_dir": "supplementary", | ||
| "group_entry": {}, |
There was a problem hiding this comment.
Preserve supplementary group keys
When a cataloged supplementary identity is promoted (currently supp:personal-ops), this empty group_entry makes _resolve_group_key() fall back to standalone. Since build_project_registry() now skips the matching supplementary entry, the generated registry no longer preserves the established DEFAULT_SUPPLEMENTARY group key operator_infra for personal-ops, silently drifting the canonical registry contract; seed this from the supplementary metadata instead of {}.
Useful? React with 👍 / 👎.
| if lifecycle_state == "active" and operating_path == "maintain": | ||
| if category == "infrastructure": | ||
| return "active-infra" | ||
| if category == "commercial": | ||
| return "active-product" |
There was a problem hiding this comment.
Keep security risks as decision-needed
For active/recent active + maintain repos in the infrastructure or commercial categories that have open high/critical Dependabot alerts, this new early return runs before the existing risk_entry.get("security_risk") check below, so they now emit active-infra/active-product instead of decision-needed. That drops security-remediation work out of the decision-needed attention counts even though build_risk_entry() still marks it as a security risk.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 06f2531ddc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| workspace_projects.extend( | ||
| _cataloged_supplementary_projects(catalog_data=catalog_data, now=now) | ||
| ) |
There was a problem hiding this comment.
Keep supplementary projects out of workspace counts
When the catalog contains personal-ops, this appends a repo-less identity that the new test says lives outside the audited Projects workspace into workspace_projects. The same combined list is later passed to _build_coverage_envelope(), whose workspace row reports source: "workspace" and project_count: len(projects), so snapshots will overstate workspace-observed projects and mislabel the supplementary source unless these entries are kept separate or the coverage counts are split.
Useful? React with 👍 / 👎.
| GPT_RAG: | ||
| owner: d | ||
| lifecycle_state: dormant | ||
| lifecycle_state: manual-only |
There was a problem hiding this comment.
Keep GPT_RAG dormant without new evidence
The previous live-catalog contract documented that the 2026-07-17 operator ruling made GPT_RAG dormant because its live-driver evidence was false; this line reclassifies it as manual-only without adding any contrary catalog note or evidence. In snapshots where GPT_RAG is present, that makes a known-dormant infrastructure repo look operator-available rather than dormant, which is lifecycle/attention drift the catalog is meant to prevent.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0f7fc8cc4b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if lifecycle_state == "active" and operating_path == "maintain": | ||
| if category == "infrastructure": | ||
| return "active-infra" | ||
| if category == "commercial": | ||
| return "active-product" |
There was a problem hiding this comment.
Keep stale alerted active repos in decision-needed
When a declared active/maintain repo is stale but has receipt-backed high/critical Dependabot alerts, build_risk_entry still leaves security_risk false because it only treats active/recent activity as security-active. This new branch then promotes that stale repo to active-* before the stale fallback, so it is presented as active product/infra instead of decision-needed despite open security alerts; compute security risk for this declared-active path or check the alert counts before promoting stale repos.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ebeeef3f4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| workspace_projects.extend( | ||
| _cataloged_supplementary_projects(catalog_data=catalog_data, now=now) | ||
| ) |
There was a problem hiding this comment.
Keep repo-less projects out of security coverage totals
When this appends personal-ops as a normal project, it has no repo_full_name and later remains outside the GitHub cohort, but _build_coverage_envelope and the snapshot rollups still count its default SecurityFields as unknown/unavailable. In a run where all 9 repo-backed Tier-0 repositories have complete receipts, the generated truth will still report GitHub security coverage as partial/unknown because of the supplementary row, which misleads downstream dashboards; exclude repo-less supplementary projects from the security denominators or mark them not applicable.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5548b8b753
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if lifecycle_state == "dormant": | ||
| return "parked" |
There was a problem hiding this comment.
Check security risk before parking dormant projects
For a cataloged dormant project on the maintain path with receipt-backed high/critical Dependabot alerts, build_risk_entry now sets security_risk=True, but this early return runs before the security-risk check. That keeps the project parked instead of decision-needed, so default-attention surfaces can miss a security decision on dormant-but-maintained repos.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 006a17d3bc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "group_entry": { | ||
| "group_key": str( | ||
| supplementary.get("group_key") or "operator_infra" | ||
| ) | ||
| }, |
There was a problem hiding this comment.
Put supplementary rows in a real section
When a cataloged supplementary project such as personal-ops is promoted, this group_entry only carries group_key. _resolve_section_marker and _resolve_group_label do not use group_key, so the generated IdentityFields falls back to Standalone Projects / Root Level, and the registry/report renderers group by that section marker. This makes a repo-less external Operator OS project appear as a root-level workspace project in the compatibility outputs, despite the catalog note and the new supplementary coverage row; include section metadata here (or a matching catalog group) so the generated surfaces do not misclassify it.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d98d47137
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if lifecycle_state == "active" and operating_path == "maintain": | ||
| if category == "infrastructure": | ||
| return "active-infra" | ||
| if category == "commercial": | ||
| return "active-product" |
There was a problem hiding this comment.
Bump the attention derivation policy version
This changes the portfolio_attention.v2 classifier semantics: an explicitly active + maintain infrastructure/commercial project now becomes active-* before the stale-project branch can park it. Snapshots generated before and after this change can therefore have different attention counts and security-cohort membership while still advertising the same DERIVATION_POLICY_VERSION, so downstream dashboards and seam checks cannot distinguish the old contract from the new one. Please bump the derivation policy version and the fixtures that pin it with this semantic change.
Useful? React with 👍 / 👎.
| coverage.append( | ||
| { | ||
| "source": "supplementary_registry", | ||
| "state": "observed", | ||
| "project_count": supplementary_project_count, |
There was a problem hiding this comment.
Keep supplementary projects out of git coverage
With this new supplementary_registry row, snapshots containing personal-ops now have an explicit repo-less, non-workspace project, but the git coverage row above still counts over projects rather than the filtered workspace_projects. In that scenario the git envelope will show a permanently unobserved Git project even when every workspace checkout was observed, because supp:personal-ops is included in the denominator but can only produce not_a_repository. Please use the workspace denominator for the git row, or separately report repo-less projects, so coverage is not misleading.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3984cd31ea
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if security.coverage_state == "complete": | ||
| complete_repo_count += 1 | ||
| scanned_count += 1 | ||
| if project.identity.top_level_dir != "supplementary": |
There was a problem hiding this comment.
Use project keys to identify supplementary rows
When a real workspace project lives under a top-level folder named supplementary/, identity.top_level_dir is also supplementary because discovery derives it from the first path segment. This predicate then drops that real repo from security rollups (and the same predicate in _build_coverage_envelope drops it from coverage counts), so GitHub coverage/alert totals under-report affected workspace projects. Use the supp: project key or explicit source/provenance marker instead of the path segment.
Useful? React with 👍 / 👎.
| workspace_projects.extend( | ||
| _cataloged_supplementary_projects(catalog_data=catalog_data, now=now) | ||
| ) |
There was a problem hiding this comment.
Guard supplementary promotion against discovered projects
If an explicitly cataloged supplementary identity is also present under workspace_root (for example, the personal-ops checkout is moved into the audited Projects tree), discover_workspace_projects() already emits the workspace project and this unconditional append adds a second supp:personal-ops row. Because the keys differ, validation does not reject it, and generated truth/default-attention counts and the registry will contain two logical copies of the same project. De-dupe against discovered names/supp keys before extending.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3b0db3783f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "active-infra", | ||
| "decision-needed", | ||
| }: | ||
| } and str(raw_project.get("repo_full_name") or "").strip(): |
There was a problem hiding this comment.
Keep missing GitHub identities in the security cohort
When a default-attention workspace project is a Git repo without a parseable GitHub origin, this new repo_full_name guard leaves cohort_member false, so portfolio truth/security-gate consumers can report a complete required cohort while silently ignoring that active repo's missing coverage. I checked the collector path: derive_default_attention_cohort now still fails closed for the same non-supp: missing repo identity, so the publish/gate path should either skip only explicit supp: repo-less identities or surface this as an unknown required cohort item instead of dropping it.
Useful? React with 👍 / 👎.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5803da8884
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| catalog_data=catalog_data, | ||
| now=now, | ||
| ) | ||
| if _normalize(str(project.get("name") or "")) not in discovered_names |
There was a problem hiding this comment.
Preserve the supplementary key for repo-less checkouts
When a known repo-less supplementary checkout such as personal-ops exists under workspace_root, this name-only filter drops the generated supp:personal-ops record and keeps the discovered project key as personal-ops with an empty repo_full_name. That project is classified as active-infra by the new catalog entry, but derive_default_attention_cohort only skips empty repo names for supp: keys, so security collection aborts with invalid canonical repository name instead of producing the 9-repo cohort. Keep the supp: identity, or otherwise mark these known repo-less discoveries before cohort derivation.
Useful? React with 👍 / 👎.
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
What
Reconcile the canonical catalog and generated portfolio truth with the operator-confirmed priority policy.
Tier 0 now contains ten logical projects:
saagpatel/operant, withoperant-publicas its local alias)Tier 1 and Tier 2 remain supporting/manual-only, and retired projects stay outside default attention.
Why
The previous PR head incorrectly classified AIGCCore as manual-only and omitted personal-ops. It also tested catalog inputs without proving the generated attention output. That could make downstream Operator OS surfaces confidently prioritize the wrong portfolio.
Implementation
Verification
uv run --all-extras --frozen pytest -q: 2931 passed, 2 skippeduv run ruff check .: passedoperator-os-producer-preflight: passed on the clean PR checkoutoperator-os-seam-linter: passed with no findingsSafety