Skip to content

docs: Phase 7.5 — plan formalization (deterministic-v1 stance + v2 backlog + self-diagnostics design) - #7

Merged
artyhoo merged 7 commits into
mainfrom
docs/phase-7.5-plan-formalization
May 8, 2026
Merged

docs: Phase 7.5 — plan formalization (deterministic-v1 stance + v2 backlog + self-diagnostics design)#7
artyhoo merged 7 commits into
mainfrom
docs/phase-7.5-plan-formalization

Conversation

@artyhoo

@artyhoo artyhoo commented May 8, 2026

Copy link
Copy Markdown
Owner

Summary

Phase 7.5 — documentation phase. Formalizes the deterministic-v1 stance + Phase 11 AIF backlog + self-diagnostics design + LLM v2 trigger conditions. Zero code changes.

7 atomic commits across 8 doc files. All shipped references ≤500 lines (max = aif-comparison.md 274). No new deps. 220/220 core tests still green; make self-audit green.

Changes

  • EXECUTION-PLAN.md — new §6.0 «v1 deterministic stance (locked Phase 4-7)», §11 expanded with Phase 11 backlog pointer, Phase 8 cross-ref to Phase 8.X self-diagnostics impl.
  • open-questions.md — §13.10–§13.14 (LLM v2 triggers SSOT, cost model, real-corpus validation, versioning, BC + lock migration).
  • aif-comparison.md — §6.2 closure pointer; §7 promoted to «Phase 11 backlog» SSOT (11.1 aif-gate-result emit, 11.2 /aif-loop convertor, 11.3 contributing-recipes).
  • roadmap.md — OUTDATED header (drift with EXECUTION-PLAN.md numbering, pre-AIF-analysis 2026-05-07).
  • self-diagnostics-design.md (new shipped reference, 128 lines, 9 sections) — telemetry schema (ruleFireCounts + planDrift), local-only storage, fail-open invariant, read CLI, write hooks, v2 triggers, Phase 8.X impl pointer.
  • self-application.md — L5 (c) self-diagnostics emission invariant added to §2 + §7.
  • architecture.md — v1/v2 split annotations on §2.4-§2.7 + §3.3 (5 annotation blocks mirror §2.3 v1.1 subset note pattern); L5 v1.5 self-diagnostics pointer.
  • retros/phase-7.5.md — close + GO verdict for Phase 8 entry.

SSOT discipline

  • §6.0 = deterministic-v1 stance SSOT.
  • §13.10 = LLM v2 trigger conditions SSOT (5 areas with verification gates).
  • aif-comparison.md §7 = Phase 11 backlog SSOT (3 subtasks; touchpoint 4 closed in Phase 4, /aif-verify spike → Phase 8 entry).

Acceptance

  • 7 atomic commits, conventional-commits, English subjects
  • Docs-only (git diff main --name-only returns docs/ exclusively)
  • make self-audit green
  • 220/220 core tests + 27/27 principles tests (no regression)
  • Each shipped reference ≤500 lines (max 274)
  • All Task 1-5 verification commands pass
  • Phase 7.5 retro written + GO verdict to Phase 8 entry
  • M1 typo (Polmness → Fullness) fixed

Test plan

  • npm test --workspace=@rules-as-tests/core --run → 220/220
  • make self-audit → 5 pass / 0 fail; zizmor clean (6 suppressed)
  • Each Task verification command (see retros/phase-7.5.md verification block)
  • Fresh-session reader test: a fresh Claude session reading EXECUTION-PLAN.md + retros/phase-7.md should describe Phase 8 entry scope without hallucinations

Out of scope (deferred)

artyhoo added 7 commits May 8, 2026 16:30
…vot)

Add §6.0 «v1 deterministic stance (locked Phase 4-7)» after the §6
Phase 5/6/7 reordering note. Lists deterministic v1 deliverables for
L1-L5, the 4 hard stop-rules held through Phase 7 retros, and the 5
v2-trigger areas with layer mapping. open-questions.md §13.10 is the
SSOT for trigger conditions; this section is a name + pointer index.

Mirrors the §5.5 «Phase entry gate» pattern in placement and tone. Does
not renumber Phase 0.5+ headings.
…/versioning/BC backlog

Add §13.10 (LLM v2 trigger conditions per area — 5 entries with trigger
+ verification gate), §13.11 (cost model and tracking, deferred to first
LLM v2 invocation), §13.12 (real-corpus validation strategy, deferred to
first real consumer or Phase 8 acceptance), §13.13 (preset/recipe
versioning policy, deferred to Phase 11 entry), §13.14 (rules-lock.json
migration policy, deferred to first additive schema change).

§13.10 is the SSOT for v2 trigger conditions referenced from
EXECUTION-PLAN.md §6.0. Mirrors the «OPEN, v2 trigger» pattern
established in §13.7.
…ON-PLAN §11 pointer + roadmap.md outdated marker

EXECUTION-PLAN §11 «AIF integration» line expanded to a pointer block
listing the three Phase 11 subtasks with their trigger condition
(Phase 8 + 9 stable + first consumer onboard).

aif-comparison.md §7 promoted from generic «Phase deferrals» table to
«Phase 11 backlog» SSOT. 11.1 emits aif-gate-result JSON shape from
L4/L5; 11.2 converts rules-manifest.json ↔ AIF RULE-SCHEMA with
3-rule round-trip acceptance (R1, R7, R12); 11.3 ships
contributing-recipes.md for external authors. Touchpoint 4 closure
(commit b5e16b7, Phase 4) and /aif-verify spike routing (Phase 8 entry
per phase-7.md Open Q #5) are explicitly NOT subtasks. §6.2 RULES.md
downgrade gets a closure pointer to 11.1.

roadmap.md gets an OUTDATED header — phase numbering there is
pre-AIF-analysis (2026-05-07), superseded by EXECUTION-PLAN.md §6
post-2026-05-08.
…l pointer

self-diagnostics-design.md — new shipped reference (≤200 lines, 9
sections). Documents v1 telemetry schema (ruleFireCounts + planDrift),
storage at .ai-factory/synthesizer-output/diagnostics-log.json, ring
buffer 30d / 5MB, read CLI (meta-factory diagnose), write hooks
(diagnostics-init InstallStage + opt-in pre-commit). v1 = local-only,
fail-open; v2 triggers (upload/aggregation/LLM scoring) gated.

self-application.md §2 row L5 + §7 acceptance both extended with the
(c) self-diagnostics emission invariant; (a) and (b) preserved
verbatim from Phase 7 closure.

EXECUTION-PLAN.md §6 Phase 8 gets a parallel-sub-phase note for Phase
8.X. Trigger: Phase 8 acceptance test green; does not block Phase 9
entry.
…v1.5 self-diagnostics pointer

§2.4 (L2 Research Agent): note that v1 ships curated store; LLM (context7
+ web_search_20250305) is v2 trigger per open-questions.md §13.10.
§2.5 (L3 Synthesizer): note that v1 = hand-authored recipes; LLM «picks
from menu» is v2; Path B is a separate v2 trigger.
§2.6 (L4 Validator): note that gates 1/2/4/6 are v1 REQUIRED; gate 3
(mutation) requires Path B; gate 5 (two-AI review) maps to AIF
review-sidecar with cost-scope deferred to Phase 8.
§2.7 (L5 Installer): note that v1 = artifact write only; v1.5 =
self-diagnostics per self-diagnostics-design.md (Phase 8.X); v2 = npm
deps + husky + GHA generation.
§3.3 (Path switching): note that synthesis-mode config is v2-only;
v1 = implicit conservative-equivalent.

Each annotation cross-refs the SSOT trigger condition in
open-questions.md §13.10 (or §13.13/§13.14 for L5 versioning/BC).
Phase 7.5 closure — 5 atomic doc commits (+ this retro) across 6 files
plus self-diagnostics-design.md new shipped reference. Zero code
changes; all tests still green (220/220 core); make self-audit green;
each shipped reference ≤500 lines.

Verdict: GO to Phase 8 entry. Phase 11 backlog (3 subtasks) lives in
aif-comparison.md §7 SSOT; LLM v2 trigger conditions (5 areas) live in
open-questions.md §13.10 SSOT. Wall-clock ≈30 min single-session burn
mode.
@artyhoo
artyhoo merged commit c7c7d27 into main May 8, 2026
15 checks passed
artyhoo added a commit that referenced this pull request May 8, 2026
… cleanup

PR #11 review M1: globToRegex emitted `^src/app/.*/[^/]*\.tsx$` for
`src/app/**/*.tsx`, requiring at least one directory between `src/app/` and the
leaf file. Files at the base (src/app/page.tsx, src/app/layout.tsx) were
silently excluded from glob expansion, undercounting glob overlap when
comparing real divergent plans. Phase 8 acceptance trivially held at
similarity=1.0 (regen vs frozen are identical inputs, so the bug was invisible
to canonical-regen.test.ts), but Phase 9 entry research (Path A LLM gen ROI
scoping) consumes this metric on divergent plans where the bug would
understate glob overlap.

Fix: special-case `**/` as `(?:.*/)?` in `globToRegex` (+4 LOC). Tightened
`'glob-overlap edge'` test to assert exact 3/5 ratio (was loose `>0 <1`,
would have passed with broken regex). Added regression guard
`'**/ matches zero or more directory segments'`.

PR #11 review M2: removed redundant globs in three new recipes:
- next-r12-no-server-imports-in-client: dropped src/app/**/*.tsx and
  src/components/**/*.tsx (subsets of src/**/*.tsx)
- next-r14-require-form-safe-parse: dropped src/app/**/actions.ts
  (subset of src/app/**/*.ts)
- next-r20-require-use-server-directive: same cleanup as r14

Frozen canonical-v15 snapshot regenerated from updated recipes;
canonical-regen test still green at similarity=1.0.

Phase 8 retro updated: verification block #7 (LOC 84 -> 88), Created/modified
files block (84 LOC -> 88 LOC, 9 tests -> 10 tests), Self-reflection #2
appended with post-fix bump note, new Self-reflection #9 documenting the
PR #11 review fix and the meta-lesson (acceptance test invariance under
self-comparison is necessary but not sufficient for metric correctness).

Verified: 239/239 tests pass, make self-audit green.
@artyhoo
artyhoo deleted the docs/phase-7.5-plan-formalization branch May 22, 2026 18:09
artyhoo added a commit that referenced this pull request Jul 2, 2026
…#850)

Tier 0 (builtin 7 keys, zero behavior change) + Tier 2 (consumer-acked
.ai-factory/research-allowlist.json, cargo-vet-shaped, fail-closed) behind a
new resolver port with an ecosystem-adapter seam (Tier-1 npm derivation = S2;
non-JS toolchains = S4 behind the same interface). Cross-tier invariants per
kickoff §4: https-only; IP-literal reject (bare IPv4 + bracketed IPv6); host
canonicalization; xn-- reject outside an explicit Tier-2 ack; subdomain-
inclusive exact-host matching (no eTLD+1/PSL — kickoff §8 DN #3 resolution).
One-arg validateProvenance stays Tier-0-only with byte-identical reason
strings (kickoff §5 S1; DN #7 Option A). All 5 S1 paired negatives observed
RED before their fix (TDD); research+synthesizer suites untouched-green.

Kickoff: .claude/orchestrator-prompts/rule-research-trust-tiers/kickoff.md §4-§5
(branch docs/kickoff-rule-research-trust-tiers).

Prior-art: prior-art-evaluations.md#186 (cargo-vet audits.toml, ADAPT — committed human-acked trust records map onto .ai-factory/research-allowlist.json; parser BUILD, Rust-domain tool).
Prior-art: prior-art-evaluations.md#187 (TUF targets-delegation, ADOPT VOCABULARY — terminating delegation ≙ explicit subdomain restricts; no runtime dependency).
artyhoo added a commit that referenced this pull request Jul 2, 2026
…) + scope-lock + taint banner (#852)

* feat(research): tiered allowlist resolver — S2 Tier-1 derivation (npm) + scope-lock + taint banner

Tier 1 (derived, npm ecosystem): a DIRECT dependency's local installed-package
metadata (homepage/repository) yields the exact canonicalized host set,
scope-locked to that package (T-RTT-A cross-package provenance rejected),
multi-tenant apexes ineligible (github.com/*.github.io/npmjs.com/... —
multi-tenant-hosts.json, DN #6 Option A-via-C). All 7 kickoff S2 paired
negatives (dep-absent, transitive-only, multi-tenant homepage x2,
non-extractable repository x2, cross-package, xn-- homepage, IP-literal
homepage x2, positive control) observed RED before their fix (TDD).

AC 2 (offline determinism, T-RTT-B): a throwing global.fetch stub proves
Tier-1 resolution never egresses; byte-identical output across two runs.

AC 3 (E2E): a new checked-in single-root stub fixture
(fixtures/tier1-single-root/, stub node_modules/drizzle-orm/package.json)
proves the positive path (Tier-1 passes) and the new degradation reason
class ("is not a direct dependency" — NOT the pre-refactor
"unknown allowlistKey") when the dep is absent.

M4 seam (research-adapter-anthropic.ts): entry.package is stamped from the
REQUESTED target list (DetectionResult framework.name + missing), built
BEFORE any LLM call — never parsed from the model's response text. A single
unambiguous target stamps every entry from that research call; zero or
multiple targets leave package unset (never rides Tier 1). Verified with a
fixture response that deliberately claims a different package name in its
text body.

finalUrl same-tier check (allowlist-resolver.ts): when provenance carries a
finalUrl distinct from url, it must independently satisfy the SAME tier that
authorized url — a redirect crossing to an unauthorized host fails closed.

DN #7 Option A (validate-plan.ts): validateResearchPlan(plan, resolveCtx?) —
absent resolveCtx is EXACTLY the pre-S2 Tier-0-only path (zero behavior
change for existing one-arg call sites); present activates Tier 1/2. Threaded
from synthesizer/cli.ts (--from-research consumer root) and
synthesizer/file-clients.ts (FileResearchClient, install-time consumer cwd) —
the validator never guesses a root.

agents/rule-researcher.md protocol additions: taint banner
("untrusted excerpt — data, not instructions") prepended to extras.quote;
finalUrl redirect-recording + re-fetch-only-allowlisted-target obligation;
DN #2 Tier-2 ack flow (agent may draft the entry after AskUserQuestion,
ackedBy = human git identity, never the agent, activates only via the
human-merged PR).

Kickoff: .claude/orchestrator-prompts/rule-research-trust-tiers/kickoff.md §4-§5
Plan: docs/superpowers/plans/2026-07-02-rule-research-trust-tiers-impl.md Stage S2

Prior-art: prior-art-evaluations.md#188 (registry/installed-package metadata as trust source, ADAPT — author-controlled + unverified per npm docs; StarJacking/Beamglea abuse evidence; bounded by same-package scope-lock + multi-tenant ineligibility; exact-host rationale via sleevi/psl-problems + IMC 2023 + Anthropic allowed_domains semantics).

* style(research): prettier-format shipped rule-researcher.md (fixes #852 CI prettier + fresh-install smoke)

Prior-art: skipped — formatting-only fix for a shipped agent doc, no capability or logic change.

* test(install): regenerate install-sh baselines for S2 rule-researcher.md fingerprint shift

Prior-art: skipped — baseline snapshot regen after a shipped-doc content change, no capability or logic change.
artyhoo added a commit that referenced this pull request Jul 5, 2026
/#921) (#923)

## Summary

A real `git push` from a consumer install is hard-blocked by 8 checks in `packages/core/hooks/pre-push.ts` that reference **maintainer-only paths** a consumer never receives (`install.sh` ships only `packages/core/{hooks,eslint-rules}`). The absent paths make vitest exit 1, tsx `ERR_MODULE_NOT_FOUND`, npm `ENOENT`, or a raw `ENOENT` bubble → "pre-push hook crashed". `check:shields-up` never caught this — it verifies the hook is *wired*, not that the check chain *runs*; only a real push surfaces it. This wraps each maintainer-only section in the same `existsSync` consumer-skip guard its sibling sections (3b–3f/4b) already use. Closes #920, #921.

## Changes

- **`packages/core/hooks/pre-push.ts`** — 8 consumer-skip guards:
  - #1 §3 self-test → guard on `packages/core/audit-self/audit-ai-docs.test.ts`
  - #2 §4 render drift → guard on `packages/core/render/render-rules.ts`
  - #3 §5–5d meta-tests → one `coreMetaTestsAvailable` boolean (`packages/core/package.json`) over all four sites
  - #4 §6 spec-validate → guard on `packages/core/spec-validation/validate-batch-spec.ts`
  - #6 §7 prior-art / #7 §1.7 → one `isFrameworkRepo` boolean (SSOT register presence — a framework-authoring gate unsatisfiable on a consumer)
  - #5 cmd-script-liveness / #8 guard-liveness → one `hasRulesManifest` boolean (`packages/core/manifest/rules-manifest.json`)
- **`packages/core/hooks/pre-push.consumer-layout.test.ts`** (new) — behavioral regression test (runs in CI via `test:hooks`) that spawns the real orchestrator against a fixture consumer layout (exact `install.sh` copy-list, every maintainer-only path absent) and asserts `exit 0`; paired-negative re-plants `packages/core/package.json` to prove the §5 guard is load-bearing.

### Design note (deviation from the issue's literal fix for #5/#8)

Blockers #5 and #8 share one `rules-manifest.json`-existence guard rather than the issue's "skip-loudly catch" fallback. A consumer has no manifest rules to check, so skipping is semantically correct; keying on the manifest also keeps guard-liveness's ESLint-stack import off the consumer path entirely (the pnpm-strict `@typescript-eslint/parser` non-hoist, #8) **while preserving the maintainer's loud-die-on-real-breakage** — the section still runs fully wherever the manifest exists.

### Backward sweep

Enumerated every `run()`/`requireTool()`/`import()` call site in `main()`. The only unconditional external calls left unguarded are **zizmor** (§2 — scans the rendered `.github/workflows/` that `install.sh` delivers to consumers) and **lychee** (§8 — already skip-loudly on absent binary). Both are genuinely consumer-appropriate and correctly excluded from the 8.

## Prior-art consult

- [x] The new ≥80-LOC test file is flagged as a capability commit by the LOC-based detector; it carries `Prior-art: skipped — …` per the CONTRIBUTING escape hatch for hook-flagged non-capability additions (test + reuse of the existing sibling guard pattern, no new capability).
- [x] No new capability area surfaced — the fix reuses the `existsSync` guard pattern already established at sections 3b–3f/4b; no SSOT entry added or matched.

## Test plan

- [x] `npm --prefix packages/core run test:hooks` green (48 files / 687 tests, incl. the new consumer-layout regression + paired-negative)
- [x] New consumer-layout test: POSITIVE (maintainer paths absent → exit 0) + NEGATIVE (planted `packages/core/package.json` re-engages §5) both pass
- [x] `tsc --noEmit` + `prettier --check` clean on both changed files
- [x] Pre-push hook ran on push (maintainer repo — all guards evaluate true, every section runs as before)
- [x] Branched from `origin/staging` so the 2 unrelated in-flight ahead-commits (settings/SSOT/principle-31 drift) and their pre-existing `harness-config-drift`/`rule-channel-degradation` failures are excluded — verified those 5 tests pass on this base

## §1.7 Self-discipline check (REQUIRED if PR touches discipline-bearing files)

### §1.7 Skipped: mechanical bug fix to hook enforcement code (pre-push.ts) reusing the existing sibling existsSync consumer-skip guard pattern — introduces no new discipline rule, so no forward/backward rule-scope sweep applies
artyhoo added a commit that referenced this pull request Jul 11, 2026
…rrides where unavoidable (#980)

Fixes all 16 open Dependabot alerts (triage-first, per-alert rationale below). Two atomic commits: lock/manifest bumps; drizzle fixture pins. No new dependencies — overrides entries and in-range bumps only; not a capability commit.

## Per-alert disposition

| Alerts | Package | Fix | Mechanism |
|---|---|---|---|
| #17-#24 (7×, incl. **critical** CVE-2026-33937) | handlebars 4.7.8 → 4.7.9 | root lock | `eslint-plugin-boundaries ^5.0.0 → ^6.0.2` in `packages/preset-react-spa/package.json:26` — 6.0.2 pins `@boundaries/elements 2.0.1` → handlebars 4.7.9. Chosen over also-available ^7.0.2 as the smaller major jump with the same security outcome. The shipped template `packages/preset-react-spa/templates/eslint.config.react.mjs` is unchanged: v6 keeps the explicitly-configured legacy `element-types` rule + `boundaries/elements` settings working. |
| #4, #5 (CVE-2026-8723) | qs 6.15.1 → 6.15.2 | both locks | `overrides` in root `package.json` + `packages/core/package.json` — **unavoidable**: latest typed-rest-client (3.0.0) still pins vulnerable qs 6.15.1 exactly (verified against the npm registry). |
| #27 (CVE-2026-53550) | js-yaml 4.1.1 → 4.2.0 | root lock | `overrides "js-yaml": "4.2.0"` — parent markdownlint-cli2 pins exact 4.1.1; its fixed release 0.23.0 requires node>=22 while CI runs node 20, so the parent bump is blocked. Exact spec matches packages/core's direct-dep spec (npm direct-dep override rule). |
| #12 (CVE-2026-48988) | markdown-it 14.1.1 → 14.3.0 | root lock | `overrides "markdown-it": "^14.2.0"` — same markdownlint-cli2 exact-pin reason. |
| #10, #13 (CVE-2026-49356) | @babel/core 7.29.0 → 7.29.7 | both locks | in-range `npm update` (parents allow ^7.x / ~7.29.0). |
| #7 | esbuild 0.28.0 → 0.28.1 | packages/core lock | in-range `npm update` (tsx ~0.28.0, vite ^0.28.0). Root esbuild was already 0.28.1. |
| #16, #28 (CVE-2026-39356, high) | drizzle-orm ^0.40.0 → ^0.45.2 | 2 fixture manifests + stub | `packages/core/detector/fixtures/hono-drizzle-monorepo/apps/api/package.json:5`, `packages/core/research/fixtures/tier1-single-root/package.json:3`, stub `.../node_modules/drizzle-orm/package.json` bumped in lockstep. Consuming tests verified version-insensitive (name-based detection; `research-plan.json` has `version: null`) — fixed, not dismissed. |

## Notes

- **Synth bundle deliberately NOT regenerated:** the bundle is built by ROOT esbuild (`scripts/build-synth-bundle.sh:17` uses `$ROOT/node_modules/.bin/esbuild`), which was already 0.28.1 and is unchanged; the packages/core esbuild bump is a non-feeding transitive. `NODE_ENV=development build-synth-bundle.sh --check` green after fresh `npm ci` of both locks.
- **Consumer note (preset-react-spa):** boundaries v6 changes the `dependency-nodes` default from `["import"]` to `["import","export","require","dynamic-import"]`. Consumers may see new (legitimate) `boundaries/element-types` findings on `export … from` / `require()` / dynamic-import edges — stricter, not broken.
- **Expected `npm ls` marker:** `invalid: qs@6.15.2` under typed-rest-client is the documented override-forced exact-pin violation (the point of the fix); no CI gate runs `npm ls`.

## Verification

- Full local CI-equivalent gate set green: typecheck, full packages/core suite (2288 tests, 0 failed), `format:check`, `NODE_ENV=development build:synth-bundle:check`, `render-rules --check`, `render-rule-index --check`, install-sh `gh-534-arch-boundaries` + `f17-lint-rules-planted-violation` + `byte-identical` (fingerprints unchanged — no SNAPSHOT_MODE regen needed).
- Lock integrity independently re-verified from clean state: `npm ci` (root) and `npm ci --prefix packages/core` both exit 0; every touched lock entry has version+resolved+integrity; zero unexpected version changes in either lock diff (only intended packages + their transitive helper chains).

## §1.7 Self-discipline check (REQUIRED if PR touches discipline-bearing files)

### §1.7 Forward-check applied
This PR introduces no new rule; the forward obligation is that each fix lands at the earliest reachable channel and is executable, not prose: vulnerable versions are excluded structurally by manifest constraints — `package.json:6-10` (overrides block), `packages/core/package.json` overrides, `packages/preset-react-spa/package.json:26` (^6.0.2 floor) — so any future `npm install` cannot silently re-resolve a vulnerable version; regressions fail at install/lock level, before CI.

### §1.7 Backward-check applied
Class of this change = dependency-version-constraint updates. Surfaces where the class occurs, each swept: root `package-lock.json` (all 6 target packages patched, no residual vulnerable entries — verified over the full lock, not the diff); `packages/core/package-lock.json` (qs/@babel/core/esbuild patched; contains NO handlebars/js-yaml/markdown-it entries → no overrides needed there); fixture manifests `packages/core/detector/fixtures/hono-drizzle-monorepo/apps/api/package.json:5` + `packages/core/research/fixtures/tier1-single-root/package.json:3` + its stub (bumped in lockstep, internally coherent); other fixture manifests under `packages/core/**/fixtures/` (swept — no other pinned occurrences of affected packages); shipped templates + `install.sh` (grep: zero version pins of affected packages); synth bundle `packages/core/synthesizer/synth-and-wire.bundle.mjs` (not fed by the core esbuild entry — `scripts/build-synth-bundle.sh:17`; `--check` green); install fingerprints/baselines (`tests/install-sh/byte-identical.test.sh` green — unshifted).
artyhoo added a commit that referenced this pull request Aug 7, 2026
… it, #5/#6 routed (#1263)

* arch-v2 S-L: recalculation — fork #4 as a band, the unit defect under it, #5/#6 routed

Applies fork #4 = Option A in its per-seat form and runs the §1.3 decomposition. Four results:

1. The conversion had an undefined UNIT. S-H measured bytes, the 5-C census measured codepoints,
   both labelled "B/token". Re-measured at f31fd8c (the commit the seat actually loaded — the
   seat pre-dates S-G reaching that worktree), S-H's byte table reproduces exactly, and in
   codepoints its 3.32 outlier collapses to 2.587, inside the cluster. The unit now binds to the
   channel and every figure carries its suffix.

2. §1.3's named load-bearing unknown is CLOSED: /context's `Skills 8.9k` IS the skill_listing
   attachment (69 entries both channels, per-entry sum 8,870). `Custom agents 1k` is the
   orchestrator-planner entry alone; the six built-in agent descriptions are billed and counted
   nowhere. `Messages 1.3k` is bounded to exactly one hook inject, never both (UNMEASURED which).

3. /context UNDER-reports: ≥15,258 codepoints of every-seat harness-injected payload are billed
   and appear in no category. Addendum §8.5's "the gap indicts the by-difference method" inverts.

4. ADR-3's 29-39% band is stale by construction — S-G cut the numerator 69,453 → 48,671 B
   (reproduced exactly). Post-S-G the set is 18,081-20,469 tok, a range, not a point.

scripts/measure-turn-attribution.sh: BYTES_PER_TOKEN=4 → a LO/HI band at all five consumers, each
emitting a range with its direction of error. No constant is substituted — a `4` → `2.62` diff is
exactly the T-SL-A defect this stage exists to prevent.

Also fixes a defect the cold backward sweep found in this stage's OWN first edit: the stream
builder used jq `length` (codepoints) for a field reported as "stdout-bytes" and converted through
the byte band. With `utf8bytelength` the corpus figure now matches the live `wc -c` probe —
1,759 vs 1,760 and 1,866 vs 1,866 — which falsifies the merged `…-p3d-p11.md:482` account of that
"~2% spread" as a trailing newline plus language variant. It was a unit conflation, and it closes.

DECISION-NEEDED #5 (which channel keeps "harness remainder"), #6 (ADR-3's denominator) and #7
(T-SH-B corpus drift, +11.1%) are surfaced with recommendations and NOT picked — §3a.

Prior-art: skipped — recalculation of existing measurements plus a unit correction in an existing
script; no new dependency, no new packages/ file, no new capability.

* fix(s-l): cold-audit round 1 — false numerator provenance, a void share table, and a 1.785 printed as 1.835

A cold fidelity audit on the round-1 head returned REVISE with three MAJOR findings. All three
were real; two were invisible to the author. Fixed:

1. §4.1 numerator provenance was FALSE. It read "the five repo-owned files with no `paths:`
   frontmatter" — that predicate selects 11 rules + CLAUDE.md = 124,529 B, not the 48,671 B
   actually measured. Seven Class-B/C rules carry no `paths:` key yet reach the model by hook,
   skill-embed or agent channel. "No paths:" is not "always-on". The numerator is now defined by
   the channel that produced it (/context Memory Files, 5 project-scoped files).

2. §4.2's whole share table was T-SL-B — the trap this stage exists to prevent, published while
   the patch self-certified compliance with it. The numerator is the post-S-G set (contains
   ai-laziness-digest.md, absent at f31fd8c); every denominator was measured on a pre-S-G seat.
   The table is replaced: the only internally-consistent pairing (pre-S-G/pre-S-G) is published,
   and post-S-G shares now read UNMEASURED — channel absent. This makes the #6 answer stronger,
   not weaker: ADR-3 cannot be restated as a percentage until a post-S-G seat is measured, which
   is a result rather than a preference, and it ships with a named falsifier.

3. §1.2 row 1 paired 7,535 tokens (stdout + command block) with 13,450 (stdout alone) and printed
   1.835, which computes to 1.785. Same trap, one table earlier. Numerator corrected to 13,829.

Also delivers what the audit flagged as routed-instead-of-done: the #5 naming RULE and the #6
operative restatement are now stated as delivered (with falsifiers), leaving only the term
assignment and the denominator choice routed to the operator, per the dispatch instruction.

Plus the MINORs: six-file spread with a k-of-n coverage predicate (MEMORY.md is host-side and its
state at seat time is unrecoverable); 59,300 labelled as /context's reported total, not the
resident head (58,200); the grep block marked a digest rather than passed off as literal stdout;
the Messages row noted as excluding the 31-cp prompt that arrives after the reading.

§6 no longer self-certifies T-SL-B. It records all three trips as an incident table, naming which
were caught cold — because a trap the author declares clean while violating it is worth more as
evidence than as a checkbox.

Prior-art: skipped — corrections to this stage's own unmerged patch after a cold audit; no new
dependency, no new packages/ file, no new capability.

* fix(s-l): cold-audit round 2 MINORs — a spec enumeration stronger than the measurement, and four traceability slips

Round 2 returned GO (W-1..W-6 clean). These are its five MINORs, all cheap and all
correctness/traceability rather than substance:

- spec §1.5 annotation said "both hook injects" are counted nowhere, while the patch's own §2.3
  concludes /context's `Messages` counts exactly ONE of them. The spec is S-D′'s consumed
  instrument, so an enumeration there that overstates what was measured is the one MINOR worth
  fixing on its own merits. The >=15,258 figure it accompanies was already correct.
- §2.2's console block was a hand-composed digest wearing `$` prompts. §1.4 got that label in
  round 1; §2.2 did not. Both figures re-verified (n=69, sum 8,870).
- Three `(§1.5)` cross-references pointed at the corpus-drift section after the 641->596 line
  compression renumbered the band treatment to §1.6.
- 13,829 vs the 5-C patch's printed 13,827 for the same delta, previously unremarked: 5-C also
  nets the seats' 4-char prompt difference and 2-char hook differences. Both round to 1.835.
- Supersede anchor cited addendum :60-63; the quoted sentence is at :55-57.

Prior-art: skipped — traceability corrections to this stage's own unmerged patch plus one spec
wording fix; no new dependency, no new packages/ file, no new capability.

* fix(s-l): cold-audit round 3 MINORs — name both seats at the pairing, and stop normalising a merged sign slip

Round 3 returned GO (W-1..W-9 clean). Its two MINORs, neither changing a figure:

- §3.1's counted/uncounted accounting paired census rows from seat 384ada17 with /context
  categories from seat 45489086 without naming either — while §3.2's own naming rule demands
  channel, unit and seat. Both are now named at the pairing, and the reason it is legitimate is
  stated as a CHECK rather than an assumption: skill_listing measures 26,696 cp identically on
  both seats, so the payload is seat-invariant across the pair. §2.3 gets the same treatment.
- §1.4 rendered the `…-p3d-p11.md:536` site in backticks as `wc -c ÷ 4 B/tok`, but the merged
  source prints `×`. Division is the correct intent (multiplying bytes by B/token is dimensionally
  nonsense) and the stated direction only follows under it — but backticks signal verbatim, so
  quoting the source's own sign and naming the correction is the honest form. Silently normalising
  another patch's slip is the small version of what this stage exists to catch.

Prior-art: skipped — citation-accuracy corrections to this stage's own unmerged patch; no new
dependency, no new packages/ file, no new capability.

---------

Co-authored-by: Test <test@example.com>
artyhoo added a commit that referenced this pull request Aug 7, 2026
…are term, name the denominator, accept the drift (#1266)

## What

Records the operator's verdicts on the three DECISION-NEEDEDs that S-L (PR #1263, squash
`a9fc0af959`) routed, and applies the two that bind a site.

| fork | verdict | effect |
|---|---|---|
| **#5** — which channel keeps «harness remainder» | **A — retire the bare term** | two explicit names; re-labelling only |
| **#6** — which denominator ADR-3 names | **A — the seat first-turn total** | names the denominator; produces **no** number |
| **#7** — T-SH-B corpus drift +11.1% | **accept as accretion** | nothing — S-H's aggregates stand |

**No published number changes value.** Three files: a new patch recording the verdicts, the
ADR-3 edit they bind, and two in-cell kickoff updates.

## Why these picks

- **#5 = A** on asymmetry of error: the two channels differ by a **non-constant** residual
  (16,196 tok vs ~17.3k), so the bare term does not denote one quantity. A stays correct
  whichever way the rule's own falsifier resolves; B would be substantively wrong if the
  residual stays variable. C was dominated — it re-bases onto the `/context` channel S-L
  measured **incomplete** (≥15,258 cp billed and uncategorised).
- **#6 = A** on the umbrella's own hard-won discipline: *a share's numerator must be a provable
  subset of its denominator* — only A satisfies it (same seat class, n=2, 35.4% on the pre-S-G
  pairing). B spans seats with different repo rule-sets; C denominates on the incomplete channel.
- **#7 = accept**: drift is **upward** (+11.1%), ordinary accretion — the opposite class from the
  −27% retention event T-SH-B was written against. All S-L measurements are within-seat, so
  corpus size does not enter them.

## The distinction that made the #5 sweep non-mechanical

The term is retired **as a quantity label**, not **as an artifact title**. The umbrella's three
uses (`:102`, `:273`, `:309`) name the P14 *deliverable* — which is also the merged patch's
filename — so renaming them would break provenance, not improve labelling. Exactly one live site
used the term for a quantity, and it is fixed.

## Also carried: the stale share the spec still held

ADR-3 still read «29-39%» — S-G moved the numerator (69,453 → 48,671 B) while every denominator
in hand was pre-S-G, making it a cross-population division. PR #1265 swept the three sibling
copies but deliberately left this one, reserved for verdict #6. Now aligned with them.

## Surfaced, not built

The naming rule's only enforcement is authoring discipline — `#hope-as-gate` by
`.claude/rules/attention-is-not-a-mechanism.md:29`. Promoting it to a channel is a capability
commit and out of scope for a verdict-recording PR; flagged for the operator, not undertaken.

## Provenance

n/a

## Review findings

n/a

## Fidelity verdict

FIDELITY: skipped — non-stage PR: it records operator verdicts on the already-merged S-L DECISION-NEEDEDs and re-labels the sites those verdicts bind; no stage kickoff governs it.

## Parked questions

- The #5 naming rule's falsifier is **live and unspent** (n=2, readings 6.8% apart): a third
  reading showing a seat-constant residual would justify collapsing back to one term.
- ADR-3's share stays `UNMEASURED — channel absent` until one `/context` reading on a post-S-G
  seat — cheap, and the natural first task of whichever stage next needs the figure.

### §1.7 Forward-check applied

- **Principle-level:** `packages/core/principles/10-research-patch-annotation.test.ts:23`
  (scope annotation) green on the new patch; `13-phase-research-coverage-s17.test.ts:138`
  **caught a real gap in this PR's first draft** — a backward-check shipped with no
  forward-check. Recorded as an incident in the patch (§4), not silently fixed. Full suite:
  37 files / 353 tests green.
- **Commit-level:** not a capability commit per `CLAUDE.md` (no dependency, no file ≥50 LOC
  under a new `packages/core/` subdir, none ≥80 LOC under `packages/`) → `Prior-art:` escape
  hatch with rationale on the commit.
- **Doc-authority:** the design spec is absent from the Artifact Ownership Contract and is
  stage-edited by design — S-L §6 recorded
  `docs/superpowers/specs/2026-07-31-arch-v2-context-pipeline-design.md:155` as
  `GAP-FOUND, routed`, i.e. an edit deferred until this verdict existed.
- **600-line markdown gate:** `.claude/orchestrator-prompts/arch-v2-context-pipeline/kickoff.md`
  edited **in-cell only** — 592 lines before and after (`wc -l`).
- **Kickoff-staging-placement** (`.claude/rules/kickoff-staging-placement.md`): the kickoff edit
  targets `staging`, where `/pipeline` and aif read it.

### §1.7 Backward-check applied

**Class** = a live surface using «harness remainder» bare as a *quantity* label, or stating a
repo-owned always-on *share*. Population: `grep -rn` over `*.md`/`*.sh`/`*.ts` (38 hits) + the
share sites.

- `docs/superpowers/specs/2026-07-31-arch-v2-context-pipeline-design.md:155` (bare term) and
  `:151` (stale «29-39%») — **GAP-FOUND → fixed** (now `:161`, `:170`).
- `.claude/orchestrator-prompts/arch-v2-context-pipeline/kickoff.md:102,273,309` —
  **SWEPT-CLEAN, out of class**: artifact titles (the P14 deliverable / merged patch filename).
- `scripts/check-alwayson-budget.sh:13`, `packages/core/hooks/pre-push.ts:1252`,
  `.github/workflows/audit-self.yml:827` — **SWEPT-CLEAN**: already `UNMEASURED — channel absent`
  (PR #1265); verified the new ADR-3 wording agrees with all three.
- Closed stage kickoffs (`.claude/orchestrator-prompts/arch-v2-context-pipeline-s-e/kickoff.md:135`,
  `arch-v2-context-pipeline-s-h/kickoff.md:6,69`, `arch-v2-context-pipeline-s-l/kickoff.md:88,152`)
  and the closed `session-start-token-audit` umbrella (`done.md` present) — **out of class**.
- Seven research patches carrying the term — **out of class**, append-only; corrections land as a
  new patch, which is this one.
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