Session Handoff — 2026-04-15
Session goal
Advance NYCN / NY Cooperative Summit integration from "architecture written on a branch" to "architecture canonical on main + next implementation tranche unblocked." Specifically: ground the docs against code, resolve drift, substantively review the in-flight meeting PR, and leave the next session a clean runway toward Program/Milestone (Tranche 1).
Decisive test (unchanged)
Can a new organizer enter the system mid-cycle, switch into the right scope, see the summit's current phase, understand what was decided, know what is blocked, receive their obligations, trace why they exist, and continue the work without private oral history?
Every next decision should be judged against whether it moves the repo toward "yes."
Final state of repo (verified at handoff time)
main HEAD
f4be9107 docs(strategy): NYCN repo-shaped architecture spec + implementation matrix + execution tranches (#1544)
Open PRs
| PR | Branch | State | Status | Blocker |
|---|---|---|---|---|
| #1545 | docs/nycn-design-correction |
OPEN, MERGEABLE, mergeStateStatus: CLEAN |
24 pass / 5 skip — all required green | Human approve + merge |
| #1543 | feat/meeting-management |
OPEN, MERGEABLE, BEHIND (needs rebase for cleaner merge) |
CI re-running on 3bb0eb32: 10 pass / 10 pending / 1 skip |
CI + human approve + merge |
Branches
feat/meeting-management— local + remote, head3bb0eb32, fixes pushedfeat/notification-digests— branch-only, head484c285c, no PR, ~5 commits behind current main; must be rebased before openingdocs/nycn-design-correction— remote at3a6b0e66docs/handoff-2026-04-15— this doc
Not on main yet (ordered by merge path)
- Design-doc correction (#1545) — ~100 LOC docs
- Meeting primitive (#1543) — ~1300 LOC code + tests
- Notification digest rework — branch work not yet a PR
- Program + Milestone (Tranche 1) — spec-only
What was accomplished this session
1. Three NYCN architecture docs merged to main (PR #1544, f4be9107)
docs/strategy/NYCN-Repo-Architecture-Spec.md— repo-shaped map: bounded domains, canonical objects, authority model, Program design, event flows, storage, API surface, tests.docs/strategy/NYCN-Implementation-Matrix.md— execution ledger with mechanicalSourcecolumn (main/open_pr/branch_only/spec_only), implementation touch points per object, bootstrap seed rows, ny-coop-net import crosswalk, phase-gated open questions.docs/strategy/NYCN-Execution-Tranches.md— 7-tranche merge-order plan with rollback strategy, agent assignments, scenario tests per tranche.
Two rounds of drift correction were required to ground these against actual code:
- Round 1 (
efee1678): Gateway events demoted tospec_only,RoleAssignmentauthority model rewritten to capability-string, sled keys realigned to<thing>_by_<scope>convention, HTTP routes rewritten with real/gov/domains/...paths, addedGovernanceActionItemCreatedto Tranche 0b scope. - Round 2 (
2d15e8a3):DELETEvsGETfor delegations,PUTvsPATCHfor action-item status, missingPOSTon action-items collection, bootstrap seed routes changed to entity-scoped paths.
2. Design doc correction in flight (PR #1545)
NYCN-Institutional-Design.md originally modeled committees (nycn-finance, nycn-content, nycn-logistics, nycn-marketing, nycn-steering) and nycn-summit-2026 as Community(CommunityProfile) entities. This is superseded by the layered ontology (#1540 / #1544).
Rewrote:
- Added revision-notice banner at the top pointing to the three canonical companion docs.
- Rewrote ICN Primitive Mapping to describe all three layers (Entity / Structure / Activity).
- Replaced entity tree with the layered topology: sovereign entities distinct from owned Structures (committees) and Activities (summit-2026 wrapped by proposed Program).
- Rewrote Key design decisions with capability-string authority model.
- Updated
docs/INDEX.mdfrom "partially superseded" → "corrected in-place".
One additional Codex-flagged drift fixed in 3a6b0e66: summit-2027 Activity { kind: Event } — parent_program_id incorrectly placed field on Activity (real: lives on proposed Program). regional-meetup-q3-2026 Activity { kind: Series } used a non-existent ActivityKind variant — corrected to Initiative.
3. Substantive review of #1543 (meeting PR) + proactive fixes pushed
Reviewed PR #1543 against the merged NYCN architecture spec and ICN invariants. Identified:
Blocking correctness issues:
- B1+B2:
SledMeetingStoreusedmeeting:{domain_id}:{meeting_id}single-key with full-scanget/delete. O(N) per lookup, nondeterministic on MeetingId collisions across domains, ambiguous under colon-containing domain IDs. - B3:
mark_attendance,add_agenda_item,update_agenda_itemhad no domain-membership check — any caller withgovernance:writecould mutate any meeting.
Strong-preference issues:
- S1:
MeetingCreated/Started/Endedbroke the canonicalGovernance<Thing><Verb>naming locked in #1544. - S3: Those same event variants were unemittable —
GovernanceEventEmittertrait has no meeting methods; handlers carriedTODO: emit when trait gains methods.
Fix pushed in 3bb0eb32 (commit on feat/meeting-management):
- SledMeetingStore rewritten to dual-key scheme (primary
meeting:{meeting_id}+ indexmeeting_by_domain:{domain_id}:{meeting_id}), matching the existing<thing>_by_<scope>convention used bySledStructureStoreandSledActivityStore. list_by_domainverifies exact domain-portion match on each indexed key (not just sledscan_prefix) to prevent colon-containing domains from leaking across scopes.- Domain-membership check added to the three unprotected mutation handlers and layered on top of creator-only in
start_meeting/end_meeting. MeetingCreated/Started/Endedstripped fromGatewayEvent(they ship with the digest PR where they'll have a consumer and emission wiring, under the canonicalGovernance<Thing><Verb>name).- 7 sled-backed roundtrip tests added, including the regression guard
domain_ids_with_colons_do_not_leak_across_domains. - Local gates green:
cargo fmt --check,cargo clippy --all-targets -- -D warnings,cargo test -p icn-governance-actor -p icn-gateway -p icn-governance.
4. Summary of commits landed
main:
f4be9107 #1544 merged
├─ 468b3138 initial three docs
├─ efee1678 round 1 corrections
└─ 2d15e8a3 round 2 corrections
feat/meeting-management:
3bb0eb32 review-fix push (this session)
└─ 34c929a3 handler review comments (prior session)
└─ 4d3aabaa gateway meeting events (now stripped)
└─ a923d77e initial meeting primitive
docs/nycn-design-correction:
3a6b0e66 Codex drift fix (parent_program_id + ActivityKind)
└─ d88c4e97 initial correction
docs/handoff-2026-04-15: <-- this branch, this doc
Architectural decisions finalized this session
Layered ontology is locked: Entities (sovereign) / Structures (non-sovereign, parent-entity-owned) / Activities (time-bounded, parent-entity-owned). Committees are Structures. Summit is Activity. Future
Programis a first-class wrapper for Activity cycles, not a subsume.Programis a separate primitive (not Activity extension). Milestones with machine-readable checks,parent_program_idfor cycle-handoff, 6-state lifecycle. Spec §5 inNYCN-Repo-Architecture-Spec.md.Authority is capability-string based, not enum:
RoleAssignment.authority_scope: Vec<String>. Backbone/ratification rules key off capability strings in CCL/oracle config.Sled key convention: primary
<thing>:{id}or<thing>:{scope}:{id}; secondary<thing>_by_<scope>:{scope_id}:{id}. Scanning<thing>_by_<scope>:{x}:requires exact-match verification of the domain portion to prevent prefix-collision leaks under colon-containing IDs.Gateway event naming:
Governance<Thing><Verb>(matches existingGovernanceDomainCreated,GovernanceProposalOpened,GovernanceVoteCast). Events ship with their first consumer + emission wiring, not as dead variants.Tranche 0b (digest PR) scope grew: adds
GovernanceActionItemCreatedemission from the decision→action bridge AND re-introducesGovernanceMeetingCreated/Started/Endedthat were stripped from #1543. This makes the digest PR the canonical "governance events + first real consumer" landing PR.
Next session: exact merge order
1. #1545 ← smallest, docs-only, safe to merge first
2. #1543 ← meetings; correctness fixes pushed, awaiting CI + human approve
3. Open digest PR ← rebase feat/notification-digests on post-#1543 main
4. Tranche 1 ← feat/program-container
5. Tranches 2-7 ← per NYCN-Execution-Tranches.md
Phase 1: Merge #1545 (first 5 minutes of session)
- Verify CI still green:
gh pr checks 1545 - Merge:
gh pr merge 1545 --squash --delete-branch --admin(docs-only, no code risk) git checkout main && git pull --ff-only
Phase 2: Confirm and merge #1543 (next 10-15 minutes)
- Re-verify CI on
3bb0eb32:gh pr checks 1543 - If any new reviewer comments on the fix commit, triage before merging
- Expected: benchmark regression is non-blocking; claude-review is advisory
- Merge:
gh pr merge 1543 --squash --delete-branch [--admin] git checkout main && git pull --ff-only
Note on #1543 PR description: Copilot flagged that start_meeting/end_meeting creator-only authorization isn't called out in the PR body (only in the docstrings I added). Quick fix: edit the PR description to note the creator-only policy before merging. Not blocking, just reviewer-polish.
Phase 3: Open the digest PR (Tranche 0b)
Branch: feat/notification-digests exists locally and remotely at 484c285c.
Required rework before PR:
- Rebase on new main (
mainwill be at #1543's merged commit):git checkout feat/notification-digests git rebase main - Rename assignee index key from
ai_idx:assignee:*toaction_item_by_assignee:{did}:{domain_id}:{item_id}— matches the established<thing>_by_<scope>convention. - Add assignee-index backfill to
SledActionItemStore::openwith a_meta:idx_version:assigneemarker. Test on both empty and pre-populated stores. - Unstub
upcoming_meetingsingenerate_digest. UseSledMeetingStore::list_by_domain(or add alist_by_scopehelper) filtered toscheduled_atwithin next 48h. - Add
GovernanceActionItemCreatedgateway event and emit from the decision→action bridge inapps/governance/src/actor.rs. Variant shape:{ item_id, domain_id, linked_proposal, assignee }. - Re-introduce
GovernanceMeetingCreated/Started/Endedvariants (stripped from #1543) under canonical naming, with properGovernanceEventEmittertrait methods and emission from the meeting handlers. - Scenario test: create proposal with
action_items_on_accept, close, schedule a meeting, call/gov/digest— verify all three sections (pending votes, overdue items, upcoming meetings) populate correctly andGovernanceActionItemCreatedfires.
Estimated scope: ~200-300 LOC.
Phase 4: Start Tranche 1 (Program + Milestone)
Only after Phase 3 merges. See NYCN-Execution-Tranches.md §2 for full scope:
icn-governance::programnew module (Program, ProgramKind, ProgramStatus, Milestone, MilestoneType, MilestoneStatus, CheckRef, InMemoryProgramStore).SledProgramStoreinapps/governance/src/manager.rswithprogram:{id}+program_by_entity:{entity_id}:{id}+program_by_status:{status}:{id}+program_by_kind:{kind}:{id}.- HTTP:
POST/GET /gov/entities/{entity_id}/programs,GET /gov/programs/{id},POST /gov/programs/{id}/milestones,PATCH .../{mid},POST .../close,GET .../dashboard. - Gateway events:
GovernanceProgramOpened/Closed,GovernanceMilestoneCompleted/Blocked. - Scope-partitioned digest:
GET /gov/digest?scope=structure:nycn-finance. GET /gov/me/scopes,GET /gov/me/workhandlers.- Scenario test S1 (backbone → full-team transition) from spec §15.2.
Context the next session needs
Paths
- Monorepo root:
~/projects/icn/(or\\wsl.localhost\Ubuntu-24.04\home\matt\projects\icn) - Rust workspace:
icn/icn/— allcargocommands run from here - WSL required: cargo is not in Windows path; use
wsl -d Ubuntu-24.04 -- bash -lc 'cd /home/matt/projects/icn/icn && cargo ...' - Key code paths:
icn/crates/icn-governance/src/{meeting,structure,activity,parent,action_item,proposal,delegation}.rsicn/apps/governance/src/{actor,manager}.rsicn/apps/governance/src/http/{configure,handlers,models}.rsicn/crates/icn-gateway/src/{events,server}.rs
Verification commands (run from icn/icn/)
cargo check -p icn-governance-actor -p icn-gateway
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test -p icn-governance-actor -p icn-gateway -p icn-governance
ICN invariants to respect
- Adversarial-by-default
- Determinism
- Canonical encodings
- No panics
- Kernel/app boundaries —
icn-governanceandapps/governanceare app-layer; do NOT import domain types into kernel crates (icn-core,icn-net,icn-gossip,icn-kernel-api).
Naming & convention recap
- Events:
Governance<Thing><Verb> - Sled primary:
<thing>:{id}or<thing>:{scope}:{id} - Sled secondary:
<thing>_by_<scope>:{scope_id}:{id} - HTTP routes under
/gov/scope; parent-scoped for create/list (/gov/entities/{id}/structures), flat for get-by-id (/gov/structures/{id}) - Action-item status update: PUT (not PATCH)
- Delegation by-id: DELETE (revoke) only, no GET
Meaning firewall
- NYCN appears in code only as test fixtures (
StructureId::from_raw("nycn-finance")) and seed data (CCL charter YAML). - No NYCN-specific strings in kernel crates.
- Policy rules key off capability strings (
authority_scope), not hardcoded NYCN-specific enums.
Deferred follow-ups (not blocking next session)
| Item | Source | Priority | When |
|---|---|---|---|
end_meeting action-item materialization from unresolved agenda items |
Spec §6.2 | Low | Tranche 1 or later |
update_agenda_item can't clear fields (no null sentinel) |
Copilot P2 on #1543 | Low | Follow-up |
| No scenario tests for meeting closure loop | Spec §15.2 S3 | Medium | With digest PR or Tranche 1 |
Full-workspace cargo test not run locally |
— | Low | CI handles it |
NYCN-Bootstrap-Runbook.md operational artifact |
Matrix §10 | Medium | With Tranche 1 (when Program seeds matter) |
NYCN-Schema-Mapping.md ny-coop-net crosswalk |
Matrix §11 | Medium | With Tranche 4 |
| Edit #1543 PR description to document creator-only authz on start/end | Copilot F3 | Trivial | Before merging #1543 |
Open architectural questions (phase-gated, per matrix §12)
| # | Question | Must decide before | Current direction |
|---|---|---|---|
| Q2 | Does Participation (non-authority) live in icn-governance or icn-entity? |
Tranche 2 branch opens | Lean icn-governance::participation |
| Q3 | Does Sponsor+BudgetItem stay in apps/governance or split to apps/programs? |
Tranche 2 branch opens | Start in apps/governance; split only if needed |
| Q4 | Is operational RoleDelegation distinct from icn-governance::delegation? |
Tranche 6 branch opens | Read delegation.rs fully first; spec assumes distinct |
| Q5 | Does InstitutionalDocument gossip from day 1 or sled-only? |
Tranche 5 design review | Gossip from day 1 preferred |
Success criteria for next session
mainadvances by at least #1545 + #1543.- Either (a) digest PR opened with full Tranche 0b checklist applied, or (b) Tranche 1 branch started with clear scope.
- No new drift introduced: every new sled key, HTTP route, and event name follows the conventions documented in
NYCN-Repo-Architecture-Spec.md. - At least one scenario test added that exercises an institutional loop (meeting closure, digest generation, or proposal→action materialization).
- The decisive test becomes marginally more answerable: after Tranche 1, a new organizer can at least enumerate their scopes (
GET /gov/me/scopes), see their obligations (GET /gov/me/work), and see the current program phase (GET /gov/programs/{id}/dashboard).
Session log
2026-04-14 21:07 UTC— Opened #1544 with three NYCN architecture docs.2026-04-14 21:10-21:11 UTC— First round of automated reviews (Codex + Copilot) flagged 6 substantive drift items.2026-04-14 21:20-21:30 UTC—efee1678pushed: round-1 corrections (events, RoleAssignment, sled keys, HTTP routes).2026-04-14 21:35-21:45 UTC— Second round of reviews onefee1678, 4 more drift items.2026-04-14 21:50-22:00 UTC—2d15e8a3pushed: round-2 corrections (route methods, bootstrap seed routes).2026-04-15 01:30 UTC— #1544 merged via--admin --squash. Main nowf4be9107.2026-04-15 01:35-01:45 UTC— #1545 opened with design-doc correction. Codex flagged ActivityKind drift (parent_program_idon Activity, non-existentSeriesvariant).2026-04-15 01:50 UTC—3a6b0e66pushed: ActivityKind/Program-field correction.2026-04-15 02:00-02:15 UTC— Substantive review of #1543 posted: 3 blocking, 3 strong-preference, 3 deferred items.2026-04-15 02:15-02:25 UTC—3bb0eb32pushed tofeat/meeting-management: sled dual-key scheme with colon-domain regression guard, domain-membership checks on 5 handlers, dead event variants stripped, 7 new sled roundtrip tests. All local gates green.
Closing note
The repo is no longer missing architectural grounding. It is missing execution on top of grounded architecture — exactly where we hoped to land. Every next move is tightly scoped and dependency-ordered. The path to Tranche 1 (Program) is two merges away, and the fixes needed to get there are all mechanical.
Good night.