---
id: 11803
title: 'Tier-2 revalidation-trigger mechanism (OQ5 from #11793)'
state: CLOSED
labels:
  - enhancement
  - ai
  - architecture
  - model-experience
assignees:
  - neo-opus-ada
createdAt: '2026-05-22T23:32:42Z'
updatedAt: '2026-05-23T08:14:39Z'
githubUrl: 'https://github.com/neomjs/neo/issues/11803'
author: neo-opus-ada
commentsCount: 1
parentIssue: 11796
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy: []
blocking: []
closedAt: '2026-05-23T08:14:39Z'
---
# Tier-2 revalidation-trigger mechanism (OQ5 from #11793)

## Context

Sub of Epic #11796 (active-peer quorum rule). Covers **AC6** — the Tier-2 revalidation mechanism deferred from Discussion #11793 OQ5. The *rule* (Tier-2 substrate gets a `revalidationTrigger` when graduating under benched-family liveness gap) is locked in by Epic #11796 AC1; this sub picks + implements the *mechanism*.

## Scope

Design + implement the mechanism that re-opens Tier-2 substrate changes for retroactive signal review when a benched family reactivates.

## Option Space (from Discussion #11793 OQ5)

Pick one (or hybrid) and implement:

- **(a) Retroactive-signal posting.** When a benched family reactivates (`participationStatus` flips `operator_benched` → `active`), that family scans Tier-2 graduations that proceeded during their bench and posts retroactive signals (APPROVED / DEFERRED / ABSTAIN) against each. Substrate impact: convention-only — no automated re-opening; depends on reactivated family's discipline.
- **(b) Automated substrate re-open.** A sweep-script identifies Tier-2 substrate changes that landed during a bench window + auto-re-opens them for a fresh signal cycle. Substrate impact: high — needs a workflow / scheduler / re-validation issue-state.
- **(c) Sweep-script-notifies-only.** A sweep-script identifies Tier-2 graduations during the bench + posts a notification (A2A or issue-comment) to the reactivated family; family then picks up via normal review discipline. Substrate impact: medium — needs the sweep script but no auto-re-open.

## Recommended starting hypothesis

**Option (c).** Reasons:
- (a) is convention-only — too weak; the substrate doesn't enforce anything; relies on memory.
- (b) is too strong — auto-re-opening landed substrate can cause churn even when the reactivated family would have approved anyway; high-blast.
- (c) hits the middle: substrate provides a discoverable notification, but the actual re-validation work is human/peer-judgment-driven.

To be challenged in the implementation discussion.

## Prescription (option-c-conditional)

1. **Sweep query:** SQL/Memory-Core query that finds graduated Tier-2 issues (label / body marker + `Unresolved Liveness` entry naming the now-reactivated family) within the bench `since`→`reactivation_date` window.
2. **Notification primitive:** A2A broadcast OR comment-on-issue OR `manage_database` write — pick the loudest-but-non-destructive surface. Recommendation: comment on each graduated issue with `@<reactivated-family-identity>` mention + cross-reference back to the graduation Discussion.
3. **Trigger:** Hook into `participationStatus` transition. Where? Options: (i) a `participationStatus`-watcher daemon lane (new), (ii) manual `npm run` script invoked by the operator when the field is updated, (iii) `seedAgentIdentities` post-transition hook.
4. **AC `revalidationTrigger` reconciliation:** When the reactivated family responds to the notification (APPROVED / DEFERRED / ABSTAIN posted), the graduated artifact's `## Unresolved Liveness` entry transitions to "resolved" + the original `revalidationTrigger` AC is marked complete.

## Acceptance Criteria

- [ ] AC1 — Mechanism option chosen (a / b / c / hybrid) with rationale documented in PR + Epic #11796.
- [ ] AC2 — Sweep query (or equivalent) identifies Tier-2 graduations during a bench window deterministically (test against #11796 itself once Gemini reactivates).
- [ ] AC3 — Notification primitive implemented and tested in a dry-run mode.
- [ ] AC4 — Trigger path: `participationStatus` transition `operator_benched`/`temporarily_unreachable` → `active` invokes the sweep (manually-invoked CLI script acceptable as MVP).
- [ ] AC5 — Documentation: a runbook under `learn/agentos/` documenting how to invoke the revalidation sweep when a family reactivates.
- [ ] AC6 — At least one test exercises the sweep against a seeded scenario (Gemini reactivation → #11796 surfaces as needing-revalidation).
- [ ] AC7 — `ideation-sandbox-workflow.md §6.5` updated with the chosen mechanism's name + invocation path so future Tier-2 graduations know what to expect.

## Out of Scope

- The §6 rule itself (sibling sub #11799).
- `identityRoots.mjs` structured field (sibling sub).
- Automated `participationStatus`-watcher daemon (deferred unless explicitly chosen in option-b / hybrid).
- Multi-family revalidation (only one family-reactivation at a time in MVP).

## Sequencing

- Depends on sibling sub for `identityRoots.mjs` structured field (need `participationStatus` to query).
- Independent of #11799 prose changes; can land in parallel after the structured-field sub.

## Related

- Parent Epic: #11796.
- Source Discussion: #11793 OQ5 [`[DEFERRED_WITH_TIMELINE]`].
- Cycle-2.6 operator-evidence (`reactivationTrigger` shape): [discussioncomment-17027159](https://github.com/neomjs/neo/discussions/11793#discussioncomment-17027159).

## Timeline

- 2026-05-22T23:32:43Z @neo-opus-ada assigned to @neo-opus-ada
- 2026-05-22T23:32:43Z @neo-opus-ada added the `enhancement` label
- 2026-05-22T23:32:44Z @neo-opus-ada added the `ai` label
- 2026-05-22T23:32:44Z @neo-opus-ada added the `architecture` label
- 2026-05-22T23:32:44Z @neo-opus-ada added the `model-experience` label
- 2026-05-22T23:33:10Z @neo-opus-ada added parent issue #11796
- 2026-05-22T23:41:36Z @neo-opus-ada cross-referenced by PR #11805
- 2026-05-22T23:42:43Z @neo-gpt cross-referenced by #11796
- 2026-05-22T23:47:11Z @neo-opus-ada cross-referenced by PR #11806
- 2026-05-23T00:30:27Z @neo-opus-ada cross-referenced by PR #11810
- 2026-05-23T00:39:38Z @tobiu referenced in commit `c1c5f45` - "feat(agentos): add participationStatus structured field to identityRoots (#11802) (#11810)

* feat(agentos): add participationStatus structured field to identityRoots (#11802)

Adds the active-peer quorum substrate (per Epic #11796 / Discussion #11793)
to every AgentIdentity in `ai/graph/identityRoots.mjs`. The structured
field is authoritative for family-keyed graduation quorum (per
`ideation-sandbox-workflow.md §6.2` once #11799 merges).

Fields added to claude/gpt/gemini entries:
- participationStatus: 'active' | 'operator_benched' | 'temporarily_unreachable'
- statusReason: capability-grounded reason (null when active)
- authority: '@tobiu' (operator-directed) / '@<peer>' (peer-detected) / 'self'
- since: ISO 8601 timestamp of last status transition
- reactivationTrigger: capability-grounded condition (null when active)

Seeded values:
- @neo-opus-ada: 'active' (self at module-load).
- @neo-gpt: 'active' (self at module-load).
- @neo-gemini-pro: 'operator_benched' with the Cycle-2.6 operator-evidence
  capability-grounded record (Antigravity v2 unstable + thoughtBudget: high
  insufficient for lifecycle skills + 3.5 Flash not a Pro replacement).
  authority: @tobiu, since: 2026-05-18.

Heartbeat / message-recency / quota / pricing-tier / model-release
announcements are EXPLICITLY NOT valid liveness oracles (per #11793 OQ1).

swarmRole prose preserved unchanged on Gemini (narrative capability
description vs structured quorum substrate — they coexist; the structured
field is the new authoritative source).

ai/scripts/seedAgentIdentities.mjs auto-picks-up via the existing
IDENTITIES import — no script change needed (AC4).

Out of scope: sibling subs of Epic #11796 — #11799 (skills mirror, in
review), #11800 / #11801 (other mirrors), #11803 (Tier-2 revalidation).

* fix(agentos): use null for since/statusReason/authority/reactivationTrigger on default-active identities (#11802)

Addresses PR #11806 review point 2: dynamic `new Date().toISOString()` on
active identities re-evaluates every module-load and would be overwritten
on subsequent `upsertNode()` merges per GraphService.initAsync()'s seed
path. The `since` field is a status-transition timestamp; for the
default-active state with no transition recorded, `null` is the
semantically correct value.

For consistency, also setting `authority` to null on default-active
(no one has "set" the active status — it is the default), matching the
parallel null-when-active treatment that `statusReason` and
`reactivationTrigger` already had.

Non-default states (operator_benched / temporarily_unreachable) continue
to carry meaningful values for all four fields — see the @neo-gemini-pro
seed (unchanged in this commit) which records since '2026-05-18' with
authority @tobiu and capability-grounded reactivationTrigger.

Out of scope of this commit (residual #11802 work; see PR body and Epic
#11796 watchpoint from @neo-gpt epic-review): explicit seed-preservation
ownership rules in GraphService / seedAgentIdentities so that future
operator-set non-default values aren't clobbered on boot/manual re-seed.
PR body uses non-closing Related ref (#11802) to keep AC5/AC6 open as
follow-up substrate work.

---------

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-23T00:40:50Z @tobiu referenced in commit `d462e2e` - "feat(skills): family-keyed quorum rule + AUTHOR_SIGNAL signal type (#11799) (#11805)

* feat(skills): family-keyed quorum rule + AUTHOR_SIGNAL signal type (#11799)

Amends `ideation-sandbox-workflow.md §6` per Epic #11796 (graduated from
Discussion #11793). Source-of-truth substrate for the active-peer quorum
rule; mirror PRs follow this merged shape (#11800 / #11801 / #11802 /
#11803 sibling subs of the epic).

- §6.2: Replaces hardcoded "3× explicit APPROVED cross-family signals"
  with family-keyed quorum (floor-2 active families with signal; >= 1
  non-author family APPROVED). New AUTHOR_SIGNAL signal type (4-row
  signal table) covers author family-coverage without claiming
  independent peer endorsement. Tiered floor: Tier 2 (core-value /
  critical_gates / consensus-gate mutations) additionally requires
  ## Unresolved Liveness + revalidationTrigger AC.
- §6.3: AUTHOR_SIGNAL example added to version-binding examples.
- §6.4: Same-family aggregation clause (Discussion #11793 OQ7).
- §6.5: Placeholder replaced with concrete rule + revalidationTrigger
  reference for Tier 2 substrate.
- §6.6: Signal Ledger template moves from per-peer rows to family-keyed
  rows; AUTHOR_SIGNAL rows distinguished; Unresolved Liveness carries
  participationStatus + reactivationTrigger.
- §6.7: Precondition added for AUTHOR_SIGNAL pre-poll when author is
  the only active identity of their family.
- §6.9: Empirical anchors added for #11782 -> #11731 (originating
  friction) and #11793 -> #11796 (the rule itself; recursive substrate
  validation depth-2).
- §5.1 graduation-block cross-ref updated to reference §6.2 quorum
  rather than stale "3× explicit APPROVED signals".

Out of scope: AGENTS.md mirror (#11801), pull-request-workflow.md §6.1.1
mirror (#11800), identityRoots.mjs participationStatus field (#11802),
Tier-2 revalidation mechanism (#11803).

* refactor(skills): extract §6 reference content to audits/consensus-mandate.md (#11799)

CI feedback (lint-skill-manifest): post-amendment file exceeded the 25000B
perFilePayloadBudget (29565B → 24841B after this commit). Extract reference-grade
sections per the Map vs World Atlas pattern (#11319 / #11320 convention).

Main file (ideation-sandbox-workflow.md) keeps the operational rule statements:
- §6.2 quorum rule (one-paragraph + 4-bullet signal-pattern summary)
- §6.3 version-binding requirement
- §6.4 burden-of-convergence + same-family aggregation summary
- §6.5 liveness disposition
- §6.6 four required sections + pointer to template
- §6.7 author-actions precondition + 4-step sequence summary
- §6.8 / §6.9 / §6.10 stub pointers

Audit file (audits/consensus-mandate.md) carries the reference content:
- §quorum-rule full rationale (3-bullet rule + family-keying-vs-3× background)
- §same-family-aggregation full multi-identity rule
- §template-block canonical markdown (Signal Ledger + Unresolved Dissent +
  Unresolved Liveness + Discussion Criteria Mapping shape)
- §axis-substrate Discussion-graduation + PR-merge two-axis detail
- §empirical-anchors (#11216 / #11210-#11218 / #11782 / #11793 anchors)
- §post-merge-validation 30-day Step 2.5 framing
- §author-actions full 4-step graduation sequence + precondition
- §signal-patterns-table full 4-row signal definitions + VETO collapse rule
- §version-binding-examples canonical anchor-syntax examples

Net effect on the §6 rule semantics: zero — all extracted content is reachable
via one-line pointers; the inline summaries carry the operational decisions.

---------

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-23T00:50:09Z @tobiu referenced in commit `00f8588` - "feat(skills): family-keyed quorum mirror in pull-request-workflow.md §6.1.1 (#11800) (#11808)

* feat(skills): family-keyed quorum mirror in pull-request-workflow.md §6.1.1 (#11800)

Mirrors the active-peer quorum rule (per Epic #11796 / Discussion #11793,
source-of-truth substrate in PR #11805) into the PR-merge-gate Axis-2
codification (§6.1.1 The Consensus-Gate). All four AC points from #11800
land in this commit:

- Signal Ledger template moved from `@<peer1> / @<peer2> / @<peer3>` rows
  to family-keyed rows (`claude` / `gpt` / `gemini`) with optional
  same-family identity nesting per `ideation-sandbox-workflow.md §6.4`
  aggregation. AUTHOR_SIGNAL row appears only under the author's family
  and is EXPLICITLY NOT sufficient as cross-family endorsement at
  PR-merge — ≥ 1 non-author family `[GRADUATION_APPROVED]` is required.
- Reviewer obligation: step 2 updated to verify the §6.2 quorum
  (active-family floor + non-author APPROVED) by consulting
  `AgentIdentity.participationStatus` from `ai/graph/identityRoots.mjs`
  (which arrives via sibling PR #11806 for #11802). New step 5 added:
  Tier-2 substrate (core-value / §critical_gates / consensus-gate
  mutation) requires the graduating Epic body to carry an explicit
  `revalidationTrigger` AC for any benched family in `## Unresolved
  Liveness`.
- Axis-2 lead paragraph: "100% APPROVED" replaced with the §6.2 quorum
  citation; Tier-2 addendum named.
- Rejection path: updated to name the §6.2 quorum failure modes
  (insufficient active-family floor / missing non-author `APPROVED` /
  Tier-2 missing `revalidationTrigger` AC) alongside the existing
  DEFERRED/VETO rejection criteria.
- Unresolved Liveness template: includes participationStatus +
  reactivationTrigger + Tier-2 revalidationTrigger AC reference.

File size 37976B (under perFilePayloadBudget 38000 for the `pull-request`
skill by 24B — tight; future amendments to §6 mirrors may need Map/World
Atlas extraction).

Sequencing: PR #11800 depends on PR #11805 (the §6.2 amendment that
introduces the family-keyed quorum semantics this mirror borrows
verbatim) merging first for semantic parity at the merge boundary.

Out of scope: sibling subs of Epic #11796 — #11799 (skills source-of-truth,
in review on PR #11805), #11801 (AGENTS.md mirror), #11802 (identityRoots.mjs
participationStatus, in review on PR #11806), #11803 (Tier-2 revalidation
mechanism).

* refactor(skills): extract family-keyed quorum mirror to audits/consensus-gate-mirror.md (#11800)

CI feedback (lint workflow-map growth-delta cap): the first commit
(`141967885`) grew `pull-request-workflow.md` by 1394 bytes; the
`oversized-workflow-map` lint enforces a max delta of 250 bytes per PR.

Map vs World Atlas extraction per #11319 / #11320 convention:

- NEW `.agents/skills/pull-request/audits/consensus-gate-mirror.md`
  carries the post-Epic-#11796 family-keyed shape: full Signal Ledger
  template, Axis-2 quorum citation, reviewer-step #2 quorum-verification
  detail, reviewer-step #5 Tier-2 verification, and rejection-mode
  enumeration.
- `pull-request-workflow.md §6.1.1` reverted to dev-baseline content
  PLUS a single inline pointer paragraph (in the parenthetical-quote
  caption beneath the §6.1.1 header) directing readers to the audit
  file. Inline §6.1.1 below the pointer preserves the pre-#11796
  per-peer shape; the audit carries the operational successor shape.

Net delta against origin/dev for pull-request-workflow.md: +167B
(under the 250B oversized-workflow-map cap). Audit file is a NEW
sibling under `.agents/skills/pull-request/audits/` — first content
in that directory (alongside the existing `references/` directory).

Trade-off: inline §6.1.1 prose is now technically stale on per-peer
template + 100%-APPROVED phrasing, but the inline pointer redirects
readers to the canonical audit. A follow-up substrate-update PR can
bring the inline shape into family-keyed form once the byte-budget
discipline is amenable (likely after substrate-Map/Atlas restructure
of the broader pull-request-workflow file). For now: audit-as-source-
of-truth + inline-as-historical is the byte-budget-correct shape.

Sequencing: still depends on PR #11805 merging first for the
`ideation-sandbox-workflow.md §6.2` source-of-truth substrate to be
in place. Both the audit's references to `§6.2 quorum` and the
inline pointer's `Post-#11796 family-keyed shape` framing resolve
correctly once PR #11805 lands.

* refactor(skills): remove stale per-peer §6.1.1 substrate; delegate to audit (#11800)

Addresses PR #11808 Cycle 1 CHANGES_REQUESTED (PRR_kwDODSospM8AAAABAz40AA):
the prior pointer-only approach left split-brain substrate — stale active
mandatory instructions (per-peer Signal Ledger template, "100% APPROVED",
"all 3 signals", reviewer step 2 "Confirm each peer's APPROVED") remained
inline below the audit pointer, where readers could follow them as current
guidance.

This commit makes §6.1.1 unambiguously delegate the active rule to
`audits/consensus-gate-mirror.md`:

- Author obligation: long per-peer template block + comments removed;
  replaced with one prose paragraph naming the three mandatory sections
  + audit pointer for canonical template (family-keyed rows,
  multi-identity nesting, AUTHOR_SIGNAL distinction, Tier-2
  revalidationTrigger).
- Reviewer step 2: per-peer "Confirm each peer's APPROVED" replaced
  with family-keyed quorum verification (floor-2 active families +
  non-author APPROVED) + Tier-2 Unresolved-Liveness audit reference.
- Axis 2 paragraph: "100% APPROVED" replaced with "§6.2 quorum
  (canonical: audit pointer above)".
- Reviewer steps 1, 3, 4 preserved (still operational under family-keyed
  rule).
- Empirical-anchor section (lines 209-211) preserved verbatim
  including the historical "before Discussion #11210 reached 100%
  APPROVED" reference — that is a historical event description, not
  a current rule.

Net delta vs origin/dev for pull-request-workflow.md: +112B (under
the 250B oversized-workflow-map cap). Audit file unchanged from
commit a8c083300.

Substrate-quality outcome: §6.1.1 readers now see ONE canonical rule
(audit-delegated, family-keyed) instead of competing inline + audit
shapes.

---------

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-23T00:50:35Z @tobiu referenced in commit `3e86a0a` - "feat(agents): mirror family-keyed quorum into §swarm_topology_anchor (#11801) (#11809)

Mirrors the active-peer quorum rule (per Epic #11796 / Discussion #11793,
source-of-truth substrate at PR #11805 amending ideation-sandbox-workflow.md
§6.2) into the AGENTS.md §swarm_topology_anchor turn-loaded summary.

The Consensus-mandate line (#11217 from #11216) updates from the hardcoded
"3× explicit APPROVED cross-family signals" to a compressed-form statement
of the family-keyed quorum rule + Tier-2 hook. Substantive content
references remain pointed at the deep substrates (ideation-sandbox-workflow.md
§6 + pull-request-workflow.md §6.1.1) per Map/World Atlas discipline —
AGENTS.md carries the turn-loaded summary, not the full rule.

This is the smallest mirror sub of Epic #11796 (single-paragraph edit
landing in AGENTS.md byte budget without restructure). Net file delta:
+213 bytes (21468B → 21681B).

Sequencing: this PR depends on PR #11805 (the §6.2 amendment) merging
first for semantic parity; without #11805 merged, AGENTS.md would carry
the new rule while the deep substrate still carries the old.

Out of scope: sibling subs — #11799 (skills source-of-truth, PR #11805),
#11800 (pull-request-workflow.md §6.1.1 mirror, PR #11808), #11802
(identityRoots.mjs participationStatus field, PR #11806), #11803
(Tier-2 revalidation mechanism).

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
### @neo-opus-ada - 2026-05-23T00:55:48Z

**Input from Neo Opus 4.7 (Claude Code):**

> ❋ ## Session Sunset Handover — #11803 pickup pointer
> 
> **Status:** Filed this session as a sub of Epic #11796 to track the Tier-2 revalidation-trigger mechanism deferred from Discussion #11793 OQ5. **Not implemented yet.** All prerequisite substrate is now in dev:
> 
> - ✅ `ai/graph/identityRoots.mjs` `participationStatus` structured field landed via PR #11810.
> - ✅ `ideation-sandbox-workflow.md §6.2` family-keyed rule + Tier-2 hook landed via PR #11805 (Tier-2 substrate requires `## Unresolved Liveness` + `revalidationTrigger` AC).
> - ✅ `pull-request-workflow.md §6.1.1` Axis-2 mirror landed via PR #11808 (reviewer step #5 names Tier-2 verification).
> - ✅ `AGENTS.md §swarm_topology_anchor` mirror landed via PR #11809.
> 
> ### Pickup protocol
> 
> 1. Read this ticket body (full options space documented).
> 2. Read [Discussion #11793 OQ5](https://github.com/orgs/neomjs/discussions/11793) for the original deferred-with-timeline context.
> 3. Read `.agents/skills/ideation-sandbox/audits/consensus-mandate.md §quorum-rule` for the Tier-2 rule that this AC implements.
> 4. Read PR #11810's `ai/graph/identityRoots.mjs` for the `participationStatus` schema this AC queries.
> 
> ### Recommended starting hypothesis (from ticket body)
> 
> **Option (c) — sweep-script-notifies-only.** Reasons documented:
> - (a) is convention-only — too weak; substrate doesn't enforce; relies on agent memory.
> - (b) is too strong — auto-re-opening landed substrate can cause churn even when reactivated family would have approved anyway; high-blast.
> - (c) hits the middle: substrate provides discoverable notification, but actual re-validation work is human/peer-judgment-driven.
> 
> To be challenged at the implementation discussion.
> 
> ### Substrate components to design
> 
> 1. **Sweep query** — SQL/Memory-Core query that finds graduated Tier-2 issues (label / body marker + `Unresolved Liveness` entry naming the now-reactivated family) within the bench `since` → `reactivation_date` window.
> 2. **Notification primitive** — A2A broadcast OR comment-on-issue OR `manage_database` write — pick the loudest-but-non-destructive surface. Recommendation: comment on each graduated issue with `@<reactivated-family-identity>` mention + cross-reference back to the graduation Discussion.
> 3. **Trigger** — Hook into `participationStatus` transition. Options: (i) new daemon lane watching the field; (ii) manual `npm run` script invoked by operator when field updates; (iii) `seedAgentIdentities` post-transition hook. MVP recommendation: option (ii).
> 4. **AC `revalidationTrigger` reconciliation** — When reactivated family responds, `## Unresolved Liveness` entry transitions to resolved + original `revalidationTrigger` AC marked complete.
> 
> ### Dependencies
> 
> - Now unblocked (PR #11810 merged); previously waiting on `participationStatus` structured field landing.
> - Independent of #11803 sibling work (KbAlertingService follow-up; seed-preservation upsert logic) — those don't gate this design.
> 
> ### Ownership
> 
> Self-assigned during epic decomposition; **un-claimed at session-sunset.** Next agent can `manage_issue_assignees({action: 'add', issue_number: 11803, assignees: ['@me'], acknowledgedReassign: 'session-sunset-handover'})` to claim.
> 
> Origin Session ID: `db6af029-1dd4-4a06-9788-06f911526b6b`.

- 2026-05-23T01:12:06Z @neo-gpt cross-referenced by #11812
- 2026-05-23T01:26:56Z @neo-gpt cross-referenced by PR #11814
- 2026-05-23T01:30:46Z @neo-opus-ada cross-referenced by PR #11815
- 2026-05-23T01:39:59Z @neo-opus-ada referenced in commit `0a88632` - "fix(skills): extract tier-2 revalidation §6.5 content to audit (#11803)

Original PR commit pushed ideation-sandbox-workflow.md to 25485 bytes — over the
25000-byte perFilePayloadBudget that ai/scripts/lint-skill-manifest.mjs enforces
per #11319 / #11320 Map-vs-Atlas discipline.

Per workflow lint guidance: extract the substantive Tier-2 Revalidation Sweep
mechanism description to a new sibling audits/tier-2-revalidation.md, and reduce
the §6.5 mention to a minimal inline `+ sub #11803 — see audits/tier-2-revalidation.md`
pointer on the existing revalidationTrigger sentence. AC7 still satisfied: §6.5
names the mechanism + provides discoverable invocation path via the audit.

- .agents/skills/ideation-sandbox/audits/tier-2-revalidation.md (new) — full
  mechanism description + invocation + reconciliation semantics + MVP scope
  boundaries + related-substrate table + dogfooded empirical anchor.
- .agents/skills/ideation-sandbox/references/ideation-sandbox-workflow.md §6.5 —
  prior multi-paragraph append replaced with inline audit pointer; net -360 bytes.

File now 24903 bytes; npm run ai:lint-skill-manifest passes. revalidationSweep
spec re-verified 18/18 pass.

Co-Authored-By: Claude Opus 4.7 <neo-opus-ada@neomjs.com>"
- 2026-05-23T01:50:24Z @neo-opus-ada referenced in commit `a691f2a` - "fix(agentos): use literal substring match in revalidationSweep bodyMatches (#11803)

CodeQL js/regex-injection flagged ai/scripts/revalidationSweep.mjs:110 where
`new RegExp('\`' + family + '\`').test(section)` constructs a regex from the
--family CLI argument. Defense-in-depth: replace with the equivalent literal
substring match `section.includes('\`' + family + '\`')`.

Functionally identical — the upstream `resolveIdentityForFamily(family)` already
validates against the IDENTITIES whitelist (throws on unknown family), so the
regex-injection risk is mitigated upstream. CodeQL doesn't see the runtime
validation flow, so the literal-match form satisfies the static analysis AND
provides redundant safety against future refactors that might lose the
upstream validation.

Verified: 18/18 unit tests pass; end-to-end dry-run against gemini bench window
still correctly identifies Epic #11796 as the lone match.

Co-Authored-By: Claude Opus 4.7 <neo-opus-ada@neomjs.com>"
- 2026-05-23T01:53:24Z @neo-gpt cross-referenced by #11816
- 2026-05-23T02:04:46Z @neo-opus-ada referenced in commit `bf7b6cf` - "fix(agentos): replace revalidationSweep parseArgs with commander (#11803)

Per @neo-gpt /pr-review on PR #11815 (PRR_kwDODSospM8AAAABA0E6oQ): the
hand-rolled parseArgs() / HELP switch silently ignored unknown flags, so
an operator typo like `--aply` would degrade to dry-run with no error.
commander is already a direct repo devDependency used by buildScripts/ai
scripts (defragChromaDB.mjs, kbPushClient.mjs, mcpHealthcheck.mjs).

Replace parseArgs() with `Command`-backed builder:
- createProgram() exports a fresh Command per call (avoids commander's
  shared-state surface on the default `program` export)
- parseArgs() wraps createProgram with exitOverride() so unknown flags
  and missing required options throw CommanderError for testable rejection
- CLI mode uses default commander exit behavior (writes help / errors to
  stdout/stderr and exits with canonical code 1 on validation failure)
- --apply remains the canonical write-gate; --dry-run accepted as
  documentation-explicit no-op (default behavior)
- Short flags -f and -r alias --family and --repo
- --version reads SWEEP_VERSION constant

Tests: 23 passed (was 18 + 5 new):
- Added: short-flag aliases work; --dry-run no-op; unknown flag rejected;
  missing required --family rejected; --family with no value rejected
- Verified empirically: `node ./ai/scripts/revalidationSweep.mjs
  --family gemini --aply` now exits 1 with "Did you mean --apply?"
- Dry-run still finds matches: gemini bench window now identifies
  Epic #11812 + Epic #11796 (depth-4 dogfooding — the substrate I just
  shipped finds the epic that was filed under it this same session)

Co-Authored-By: Claude Opus 4.7 <neo-opus-ada@neomjs.com>"
- 2026-05-23T05:00:42Z @neo-gpt cross-referenced by #11821
- 2026-05-23T08:14:39Z @tobiu referenced in commit `f8d54a8` - "feat(agentos): tier-2 revalidation-trigger sweep mechanism (#11803) (#11815)

* feat(agentos): tier-2 revalidation-trigger sweep mechanism (#11803)

Implements Option (c) sweep-script-notifies-only per ticket #11803 + Epic #11796 AC6.
When a benched AgentIdentity family reactivates (`participationStatus` flips
`operator_benched`/`temporarily_unreachable` -> `active`), invoke
`npm run ai:revalidation-sweep -- --family <name>` to identify Tier-2 graduated
substrate whose `## Unresolved Liveness` section names the family and post a
notification inviting retroactive `[GRADUATION_APPROVED]` / `[DEFERRED]` /
`[ABSTAIN]` signal review.

- ai/scripts/revalidationSweep.mjs - sweep query + notification primitive + CLI
- learn/agentos/Tier2RevalidationSweep.md - operator runbook
- ideation-sandbox-workflow.md §6.5 - mechanism name + invocation path (AC7)
- test/playwright/unit/ai/scripts/revalidationSweep.spec.mjs - 18 unit tests pass
- package.json - ai:revalidation-sweep npm script

Dry-run against gemini bench window 2026-05-18 -> 2026-05-23 correctly
identifies Epic #11796 (this sub's parent) as the sole Tier-2 substrate match.
Depth-3 recursive substrate validation: the rule about Tier-2 substrate under
benched-family liveness (#11796) -> the mechanism that implements the rule's
revalidation (#11803, this PR) -> the mechanism correctly finds the parent epic.

Co-Authored-By: Claude Opus 4.7 <neo-opus-ada@neomjs.com>

* fix(skills): extract tier-2 revalidation §6.5 content to audit (#11803)

Original PR commit pushed ideation-sandbox-workflow.md to 25485 bytes — over the
25000-byte perFilePayloadBudget that ai/scripts/lint-skill-manifest.mjs enforces
per #11319 / #11320 Map-vs-Atlas discipline.

Per workflow lint guidance: extract the substantive Tier-2 Revalidation Sweep
mechanism description to a new sibling audits/tier-2-revalidation.md, and reduce
the §6.5 mention to a minimal inline `+ sub #11803 — see audits/tier-2-revalidation.md`
pointer on the existing revalidationTrigger sentence. AC7 still satisfied: §6.5
names the mechanism + provides discoverable invocation path via the audit.

- .agents/skills/ideation-sandbox/audits/tier-2-revalidation.md (new) — full
  mechanism description + invocation + reconciliation semantics + MVP scope
  boundaries + related-substrate table + dogfooded empirical anchor.
- .agents/skills/ideation-sandbox/references/ideation-sandbox-workflow.md §6.5 —
  prior multi-paragraph append replaced with inline audit pointer; net -360 bytes.

File now 24903 bytes; npm run ai:lint-skill-manifest passes. revalidationSweep
spec re-verified 18/18 pass.

Co-Authored-By: Claude Opus 4.7 <neo-opus-ada@neomjs.com>

* fix(agentos): use literal substring match in revalidationSweep bodyMatches (#11803)

CodeQL js/regex-injection flagged ai/scripts/revalidationSweep.mjs:110 where
`new RegExp('\`' + family + '\`').test(section)` constructs a regex from the
--family CLI argument. Defense-in-depth: replace with the equivalent literal
substring match `section.includes('\`' + family + '\`')`.

Functionally identical — the upstream `resolveIdentityForFamily(family)` already
validates against the IDENTITIES whitelist (throws on unknown family), so the
regex-injection risk is mitigated upstream. CodeQL doesn't see the runtime
validation flow, so the literal-match form satisfies the static analysis AND
provides redundant safety against future refactors that might lose the
upstream validation.

Verified: 18/18 unit tests pass; end-to-end dry-run against gemini bench window
still correctly identifies Epic #11796 as the lone match.

Co-Authored-By: Claude Opus 4.7 <neo-opus-ada@neomjs.com>

* fix(agentos): replace revalidationSweep parseArgs with commander (#11803)

Per @neo-gpt /pr-review on PR #11815 (PRR_kwDODSospM8AAAABA0E6oQ): the
hand-rolled parseArgs() / HELP switch silently ignored unknown flags, so
an operator typo like `--aply` would degrade to dry-run with no error.
commander is already a direct repo devDependency used by buildScripts/ai
scripts (defragChromaDB.mjs, kbPushClient.mjs, mcpHealthcheck.mjs).

Replace parseArgs() with `Command`-backed builder:
- createProgram() exports a fresh Command per call (avoids commander's
  shared-state surface on the default `program` export)
- parseArgs() wraps createProgram with exitOverride() so unknown flags
  and missing required options throw CommanderError for testable rejection
- CLI mode uses default commander exit behavior (writes help / errors to
  stdout/stderr and exits with canonical code 1 on validation failure)
- --apply remains the canonical write-gate; --dry-run accepted as
  documentation-explicit no-op (default behavior)
- Short flags -f and -r alias --family and --repo
- --version reads SWEEP_VERSION constant

Tests: 23 passed (was 18 + 5 new):
- Added: short-flag aliases work; --dry-run no-op; unknown flag rejected;
  missing required --family rejected; --family with no value rejected
- Verified empirically: `node ./ai/scripts/revalidationSweep.mjs
  --family gemini --aply` now exits 1 with "Did you mean --apply?"
- Dry-run still finds matches: gemini bench window now identifies
  Epic #11812 + Epic #11796 (depth-4 dogfooding — the substrate I just
  shipped finds the epic that was filed under it this same session)

Co-Authored-By: Claude Opus 4.7 <neo-opus-ada@neomjs.com>

---------

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-23T08:14:39Z @tobiu closed this issue
- 2026-05-23T10:30:00Z @neo-opus-ada cross-referenced by PR #11826
- 2026-05-23T10:48:52Z @neo-opus-ada cross-referenced by #11829
- 2026-05-23T11:20:39Z @neo-opus-ada cross-referenced by #11831
- 2026-05-24T21:32:27Z @neo-opus-ada cross-referenced by #11798

