Skip to content

docs(repo): resolve Tier-3 plan-readiness audit findings#118

Merged
Sawmonabo merged 1 commit into
developfrom
docs/tier-3-plan-003-audit
May 26, 2026
Merged

docs(repo): resolve Tier-3 plan-readiness audit findings#118
Sawmonabo merged 1 commit into
developfrom
docs/tier-3-plan-003-audit

Conversation

@Sawmonabo
Copy link
Copy Markdown
Owner

Summary

NS-15 — Tier-3 plan-readiness audit of Plan-003 (Runtime Node Attach). Swaps the audited working copy into the corpus and lands the cross-cutting contract shapes the audit ratified. Plan-003 stays approved — every amendment is additive / surface-forwarding / correctness-correction.

Audit runbook: docs/operations/plan-implementation-readiness-audit-runbook.md. This is the Tier-3 pass (Tier-2 = NS-12 merged; G6 satisfied).

Decisions ratified (D1–D3)

# Decision Disposition
D1 Status disposition Stays approved — all amendments additive / surface-forwarding / correctness-correction; 0 status-flips (B6=0)
D2 Cross-corpus strategy Option C — NS-15 ratifies the api-payload + Postgres contract shapes (canonical-when-merged); the heartbeat threshold (D3d) goes to a separate Spec-003 PR (distinct governance lifecycle)
D3 Per-item contract shapes 3a clientVersion EventEnvelopeVersion + client_version column · 3b derived readOnly boolean · 3c runtimenode.* namespace · 3d → separate Spec-003 PR · 3e presence node-global (ratify, no diff)

D1 — why "stays approved" (steel-manned)

Three amendments are literal flip-triggers under the runbook rule (new Cross-Plan Obligation / new Required-ADR / behavior-change). Surfaced rather than buried, because D1 is the one place the audit verdict can be overruled:

  • CP-003-3 (new Cross-Plan Obligation) imposes no new obligation on Plan-003 — it surfaces a boundary already implicit in cross-plan-deps §2 (apps/desktop/src/renderer/ is Plan-023-owned) + Spec-023 §Trust Stance. Plan-003 consumes the window.sidekicks bridge; it does not build it.
  • Required-ADRs +005/009/023 are tagged "transitive/substrate pointers (not Plan-003 decisions)" — none is a decision Plan-003 makes (ADR-009 = the daemon SDK rides the Plan-007 wire; ADR-023 = the Phase-5 renderer runs under the Plan-023 CI surface; ADR-005 = the capability model).
  • Phase-2 event split resolves a latent contradiction (Phase 2 "emission paths for 7 events" vs Phase 3 "degraded/offline transitions"); end-state — all 7 events emit with correct triggers — is unchanged.

Matches every prior tier audit (NS-13b / NS-24 / NS-25 / NS-26 stayed approved on additive Tasks-block amendments). If the rule is read strictly and CP/Required-ADR additions must flip regardless of framing: Plan-003 → review, and a re-review pass is owed before any Tier-4 code consumes it (Tier-4 is several tiers out — procedural cost, not schedule-critical).

D2 — why Option C

One squash-commit = one governance lifecycle. The api-payload/Postgres edits are docs/architecture/ (canonical-when-merged, no draft→review→approved gate) and belong with the plan that drives them. The Spec-003 §Default-Behavior amendment re-discharges the Spec-Status Promotion Gate — a different lifecycle — so it ships as its own reviewable unit. Option A (fold Spec-003 in) conflates two lifecycles in one squash; Option B (defer all four) leaves Phase 3 unbuildable (T3.2/3.3/3.4 need the field, the read-only repr, and the namespace ratified now).

D3 — contract shapes

3a — clientVersion type-binds to the existing EventEnvelopeVersion brand (semver MAJOR.MINOR), not a parallel regex string. ADR-018 §Decision #3/#7 tie min_client_version to MAJOR envelope bumps, so the reported field is the envelope version the daemon speaks. Persisted as client_version TEXT NOT NULL so the read-only verdict derives from a stored fact (survives a later floor raise) and the roster displays it without a live daemon round-trip. Caveat: the comparison is semver-aware (MAJOR.MINOR), not lexicographic ("10.0" > "9.0" fails under string-sort) — T3.3 owns the comparator; the wire field is just the branded value.

3b — readOnly is a derived boolean on the response, orthogonal to NodeState. Liveness (NodeState) and permission (read-only) are orthogonal axes — a node can be online and readOnly. Folding read-only into NodeState loses that. Derived (client_version < min_client_version) = single source of truth, no denormalized boolean that goes stale on a floor raise. No Postgres state-CHECK change.

3c — runtimenode.* namespace. The obvious runtime_node.* form is regex-rejected by METHOD_NAME_FORMAT = /^[a-z][a-z0-9]*(\.[a-z][a-z0-9]*)+$/ (no underscores). runtimenode is the concatenated form of the established domain noun (runtime_node_* tables, runtime_node.* events) — least-invented vs the generic/ambiguous node.*. runtimenode.capabilityupdate is the first multi-word procedure in the system; lowercase run-on (2-segment) matches the uniform session.* arity and is mechanically safe on the JSON-RPC side. Lands as a new Tier-3 subsection, not an injection into the Tier-1 tRPC/JSON-RPC registries.

3e — presence cardinality ratified node-global (no diff): runtime_node_presence PK = node_id; heartbeat reflects daemon-process liveness (one process → one health state); a node in N sessions has N attachment rows but one presence row; the roster derives per-session presence by joining attachments→presence on node_id.

Naming note (preempting the clientVersion overlap)

RuntimeNodeAttachRequest.clientVersion (EventEnvelopeVersion brand, Plan-003 control-plane attach, floor-governing) is intentionally distinct from the pre-existing DaemonHelloParams.clientVersion (free-form string, Plan-007 local-IPC handshake). Same name at different layers — each internally consistent ("client" = the connecting party at that layer). The brand alignment with min_client_version / client_version is load-bearing per ADR-018 §Decision #3/#7; renaming would diverge from the canonical floor-name chain.

File manifest

File Change
docs/plans/003-runtime-node-attach.md Working-copy swap: 5 #### Tasks blocks (29 tasks: T1.1–7, T2.1–6, T3.1–8, T4.1–4, T5.1–4); runtime-node table-CREATE ownership corrected to Plan-003-owned; W2 Precondition checked; Required-ADRs row; CP-003-3; Plan-007-partial dependency; cite fixes
docs/architecture/contracts/api-payload-contracts.md 3a clientVersion: EventEnvelopeVersion on RuntimeNodeAttachRequest · 3b readOnly: boolean on the response · 3c runtimenode.* Tier-3 method-name registry
docs/architecture/schemas/shared-postgres-schema.md 3a client_version TEXT NOT NULL on runtime_node_attachments
docs/backlog.md BL-131 (Plan-003 Phase-5 renderer automated coverage; V1.1; criterion-gated on the Plan-023 renderer test harness)
docs/architecture/cross-plan-dependencies.md §6 fold (below)

Tag on merge: plan-readiness-audit-tier-3-complete.

Separate follow-up PR (not this one): Spec-003 §Default Behavior — heartbeat degraded→offline threshold + sweep owner (proposed: degraded after 2 missed beats/30s, offline after 4/60s, backstop sweep every 30s — that PR decides). Re-discharges the Spec-Status Promotion Gate. T3.6 forward-references it and invents no values.

§6 fold (cross-plan-dependencies.md)

  • NS-15 :::ready:::completed; PRs checkbox [x] tier-3.
  • NS-16 promoted blockedready (Tier-3 upstream now complete).
  • Plan-002 Phase-5/6 tracking correction (discharges the NS-13b forward-reference): added NS-28 (Plan-002 Phase 5 — membership client SDK, :::ready, grounded in PR feat(client-sdk): Plan-002 P5 membership client SDK #117 open/CLEAN as of 2026-05-26) and NS-29 (Plan-002 Phase 6 — session-members renderer, :::blocked behind NS-28), with NS26 → NS28 → NS29 edges + detail entries.
  • Ready set after this PR: {NS-16, NS-28}; blocked set: {NS-09, NS-10, NS-17..NS-21, NS-29}.

Findings ledger — 31 findings, 7 critical-instances → 4 root causes

Root-cause critical Flagged in Disposition
clientVersion absent P1 (contract-def) · P3 (attach) · P4 (SDK) 3a — api-payload + Postgres
read-only representation P3 (crit) · P4 (major) 3b — derived boolean
method namespace unratified / regex-invalid P4 (×2: no-names + regex) 3c — runtimenode.*
heartbeat threshold unspecified P3 3d — separate Spec-003 PR

7 phase-instances → 4 roots is the healthy re-flag pattern (each consuming phase independently surfaced the same upstream gap from its own vantage), not over-flagging. Majors (8): read-only-repr + tRPC/router (fold into roots above) · presence cardinality (3e, ratify) · no-automated-renderer-test (→ BL-131, V1.1-deferred with a named criterion) · Phase-1/2 cite/ADR/ownership (Tier-A, in the swap). No orphan majors. DT-003-4 (table-ownership) resolved in the working copy.

Calibration + gates

B1–B6: B1 avg-critical/phase 1.4 (target 0–2; max-phase 3 ≤ 4) ✓ · B2 total 31 (5–50) ✓ · B3 Tasks:blocking 7.25:1 root / 4.1:1 instance (≥2:1) ✓ · B4 user-review ~45–75 min (30 min–2 hr) ✓ · B5 2 substantive advisor calls + step-10 (≥1, ≤5) ✓ · B6 0 status-flips (0–1) ✓

G1–G6: G1 skeleton additions-only (CP-003-3 + 5 Tasks subsections; 0 deleted headers) ✓ · G2 all 4 root criticals dispositioned (3 here, 1 → Spec-003 PR) ✓ · G3 ex-Tasks diff 1.03× (<1.5×); max 8 step-entries/Phase ≪ 50 ✓ · G4 29/29 Tasks Steps → Spec coverage + Verifies-invariant ✓ · G5 0 new PR #N refs in the audited plan ✓ · G6 Tier-2 committed (NS-12 merged) ✓ · no-ephemeral-tags: 0 F-003-* / DT-003-* / PR #N tags in any committed file ✓

Test plan

  • pnpm install --frozen-lockfile provisioned the worktree; all pre-commit + commit-msg hooks green (gitleaks no leaks; lychee 259 links / 241 OK / 0 errors / 18 excluded; docs-corpus governance cite-walk; lint-staged prettier; commitlint).
  • 0 ephemeral F-003-* / DT-003-* / PR #N tags in any committed file (no-ephemeral-tags discipline).
  • Mermaid coherence: no duplicate NS16 node, no dangling edges; ready/blocked sets consistent with the edge set.
  • clientVersion naming overlap with DaemonHelloParams verified non-conflicting (different interfaces / different layers).

Refs: Plan-003, ADR-018, BL-131

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cc24338ecb

ℹ️ 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".

Comment thread docs/plans/003-runtime-node-attach.md Outdated
Comment thread docs/plans/003-runtime-node-attach.md Outdated
@Sawmonabo Sawmonabo force-pushed the docs/tier-3-plan-003-audit branch 2 times, most recently from 2a41884 to a413cfc Compare May 26, 2026 05:33
@Sawmonabo
Copy link
Copy Markdown
Owner Author

@codex

@Sawmonabo
Copy link
Copy Markdown
Owner Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a413cfc021

ℹ️ 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".

Comment thread docs/plans/003-runtime-node-attach.md Outdated
Comment thread docs/plans/003-runtime-node-attach.md Outdated
Comment thread docs/plans/003-runtime-node-attach.md Outdated
Comment thread docs/plans/003-runtime-node-attach.md Outdated
@Sawmonabo Sawmonabo force-pushed the docs/tier-3-plan-003-audit branch from a413cfc to 0a9ddbc Compare May 26, 2026 06:54
@Sawmonabo
Copy link
Copy Markdown
Owner Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a9ddbc698

ℹ️ 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".

Comment thread docs/plans/003-runtime-node-attach.md Outdated
@Sawmonabo Sawmonabo force-pushed the docs/tier-3-plan-003-audit branch from 0a9ddbc to 6249995 Compare May 26, 2026 07:19
@Sawmonabo
Copy link
Copy Markdown
Owner Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6249995505

ℹ️ 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".

Comment thread docs/architecture/contracts/api-payload-contracts.md Outdated
Comment thread docs/plans/003-runtime-node-attach.md Outdated
@Sawmonabo Sawmonabo force-pushed the docs/tier-3-plan-003-audit branch from 6249995 to a52e16e Compare May 26, 2026 07:47
@Sawmonabo
Copy link
Copy Markdown
Owner Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a52e16e79d

ℹ️ 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".

Comment thread docs/architecture/schemas/shared-postgres-schema.md Outdated
NS-15 — Tier 3 plan-readiness audit of Plan-003 (Runtime Node Attach).
Swaps the audited working copy into the corpus (5 #### Tasks blocks, 29
tasks; runtime-node table-CREATE ownership corrected to Plan-003-owned)
and lands the cross-cutting contract shapes the audit ratified:

- api-payload-contracts.md: clientVersion (EventEnvelopeVersion brand)
  on RuntimeNodeAttachRequest; derived readOnly boolean on the response
  (orthogonal to NodeState); runtimenode.* method-name registry (Tier 3,
  per the canonical METHOD_NAME_FORMAT).
- shared-postgres-schema.md: client_version column on
  runtime_node_attachments.
- backlog.md: BL-131 (Plan-003 Phase-5 renderer automated coverage,
  V1.1, criterion-gated on the Plan-023 renderer test harness).
- cross-plan-dependencies.md section 6: NS-15 -> completed; NS-16
  promoted blocked -> ready; Plan-002 Phase-5/6 tracking correction
  (NS-28 + NS-29 nodes, edges, detail entries), discharging the NS-13b
  forward-reference.

The Spec-003 heartbeat degraded->offline threshold (D3d) lands in a
separate Spec-003 PR (distinct governance lifecycle). Plan-003 stays
approved (D1); every amendment is additive / surface-forwarding /
correctness-correction. B1-B6 + G1-G6 pass.

Review-round resolutions (Codex + pre-merge advisor, a413cfc -> HEAD):

- T3.2 attach is an upsert (INSERT ... ON CONFLICT (node_id,
  session_id) DO UPDATE): reconnect reactivates an offline row
  (Spec-003 L65/L90), a revoked row is refused (terminal per
  runtime-node-model.md), and a cross-session active attach is
  rejected by the new idx_node_attachments_active partial unique index.
- New invariant I-003-5 (one active session per node in v1) backs that
  index; T1.3/T3.6/T3.7 resolve heartbeat/detach to the single active
  attachment by nodeId (no sessionId on the wire).
- T3.4 uses the imported VERSION_FLOOR_EXCEEDED_CODE constant, not a
  re-spelled string literal.
- runtimenode.heartbeat/detach get named z.null() no-content response
  schemas: result: null over JSON-RPC, and a null-payload HTTP 200
  { result: { data: null } } envelope over tRPC; api-payload registry
  cells + T4.1 SDK contract note updated.
- T3.2's two refusals project as typed CONFLICT (409) wire errors via
  T3.4's catch-arm + errorFormatter pattern (cross-session caught on
  SQLSTATE 23505); P9 reworded, P10 added, enumerated-test count 23->25.

Round-2 re-review (0a9ddbc -> HEAD):

- T3.1's control-plane migration is version 3 (0003-runtime-nodes.ts),
  not 0002: v2 is taken by Plan-002's 0002-session-invites, and the
  migration-runner.ts header pre-allocates v3+ to Plan-003. Append
  { version: 3, sql } to MIGRATIONS after v2 in ascending version
  order. Files now lists migration-runner.ts (extended); the test
  applies 0003 against a DB already migrated through 0002.

Round-3 re-review (6249995 -> HEAD):

- Corrected the tRPC void-mutation shape for heartbeat/detach. A tRPC
  resolver returning null surfaces as a normal HTTP 200 envelope
  { result: { data: null } } (control-plane uses the default
  transformer, no data.json wrapper), not a 204: the SDK's
  parseTrpcResult calls response.json() on every 2xx response, so an
  empty 204 body would throw SyntaxError. The z.null() schemas are
  unchanged; fixed 6 doc sites (api-payload-contracts.md 487/506/518/
  520/522 + plan T1.3 step).
- Fixed I-003-5 "Why load-bearing": nodeId-only heartbeat/detach
  resolve via the idx_node_attachments_active partial UNIQUE(node_id)
  index, not a non-existent (node_id, session_id) index "filtered to
  active states". The composite idx_node_attachments_node is the upsert
  ON CONFLICT target, not the resolution path for nodeId-only reads.

Round-4 re-review (a52e16e -> HEAD):

- Aligned the idx_node_attachments_active schema comment with terminal
  revocation. The partial UNIQUE excludes both 'offline' and 'revoked'
  rows from active-uniqueness (index mechanics), but reattach
  eligibility is a T3.2 decision: an 'offline' row reconnects, a
  'revoked' row is refused (terminal per T3.2/P10). The prior wording
  ("offline / revoked rows do not block a later (re)attach") read as
  license to reactivate revoked nodes. Verified T3.6/T3.7 step text
  defers nodeId-only resolution to I-003-5 (no F2-class re-description).

Refs: Plan-003, ADR-018, BL-131
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Sawmonabo Sawmonabo force-pushed the docs/tier-3-plan-003-audit branch from a52e16e to 5f038f4 Compare May 26, 2026 08:06
@Sawmonabo
Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

ℹ️ 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".

@Sawmonabo Sawmonabo merged commit 030c4ec into develop May 26, 2026
8 checks passed
@Sawmonabo Sawmonabo deleted the docs/tier-3-plan-003-audit branch May 26, 2026 08:45
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