Skip to content

research: AceHack/LFG cost-parity audit (Otto-61/62 directive)#11

Merged
AceHack merged 1 commit intomainfrom
research/acehack-lfg-cost-parity-audit-otto-62
Apr 23, 2026
Merged

research: AceHack/LFG cost-parity audit (Otto-61/62 directive)#11
AceHack merged 1 commit intomainfrom
research/acehack-lfg-cost-parity-audit-otto-62

Conversation

@AceHack
Copy link
Copy Markdown
Owner

@AceHack AceHack commented Apr 23, 2026

Summary

First-pass findings on the AceHack vs LFG cost-parity audit the human maintainer asked for in Otto-61. Lands on AceHack per the Amara authority-axis split (experimentation/measurement → AceHack; decisions → LFG).

Key findings

  • Linux Actions: parity — both repos public, unlimited free
  • macOS-14: LFG already avoids it via gate.yml matrix (cost-aware)
  • LFG monthly baseline: ~$27/mo (Team plan $8 + Copilot Business $19 × 1 seat active) — confirmed by human-maintainer
  • AceHack gets us nothing material that would limit LFG — LFG has richer features (Team + Copilot Business), not fewer
  • 4 BACKLOG candidates named: parity-audit tool, admin:org billing pass, enable dependabot on AceHack (free), ADR documenting baseline

What this PR is NOT

  • Not a migration away from LFG (active work stays driven by purpose, not cost)
  • Not verified billing data (needs admin:org scope elevation — authorized but not yet applied)
  • Not a commitment to scale Copilot seats

Test plan

  • Markdown renders correctly
  • Numbers reflect human-maintainer Otto-62 1-seat correction

🤖 Generated with Claude Code

…ings

Human-maintainer Otto-61 directive: "we should parity check for costs
and see if there is really anyting AceHack gets us for free that
would limit us on LFG". This PR lands the first-pass findings as an
in-repo research doc, per the Amara authority-axis split —
experimentation / measurement tooling goes on AceHack.

Observable findings (agent read-only API):

- Both repos PUBLIC → Linux Actions unlimited free on both
- LFG = Organization on Team plan (2 seats filled)
- AceHack = User account, fork of LFG
- gate.yml matrix already avoids macOS-14 on LFG (cost-aware)
- LFG has dependabot_security_updates ENABLED; AceHack does not
  (but AceHack could enable it free on public repos)

Confirmed cost structure (human-maintainer Otto-62):

- LFG Team plan: ~$8/month (2 seats × $4)
- LFG Copilot Business: ~$19/month (1 seat active per human-
  maintainer Otto-62 correction — may scale up later)
- LFG baseline: ~$27/month flat before any Actions usage

Unobservable without admin:org scope (authorized by human-maintainer
Otto-62 but requires interactive `gh auth refresh`):

- Actual Actions minute consumption per month
- Full Copilot seat allocation and usage history
- Invoice-level billing + projected monthly total

Conclusion: "go wild" authorization on public Actions stands;
Amara authority-axis split (experiments→AceHack, decisions→LFG)
is the semantic driver, not cost. AceHack gets no material free
feature that LFG is missing. LFG has richer features (Team +
Copilot Business), not fewer.

BACKLOG candidates named in the doc:
  1. Parity-audit tool (S effort; AceHack)
  2. admin:org elevation pass for billing data
  3. Enable dependabot on AceHack (free, increases parity)
  4. ADR documenting LFG baseline ~$27/mo

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@AceHack AceHack merged commit 5b2f1ac into main Apr 23, 2026
7 of 8 checks passed
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: 040b814896

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

billing-side of this audit.
3. **Enable dependabot_security_updates on AceHack** (free,
increases parity). One-click through repo settings.
4. **Document the LFG baseline $46/mo** in an ADR so future Otto
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Correct LFG baseline amount in backlog recommendation

The document consistently derives the LFG baseline as ~$27/mo (Team $8 + Copilot Business $19), but this recommendation asks to document $46/mo, which contradicts the rest of the audit and would propagate an incorrect cost baseline into any follow-up ADR or budgeting decisions.

Useful? React with 👍 / 👎.

AceHack added a commit that referenced this pull request Apr 24, 2026
…(Amara action #2) (Lucent-Financial-Group#223)

Amara's 4th ferry (PR Lucent-Financial-Group#221) action item #2: pin Claude model
snapshot + loaded memory state + prompt bundle hash so "Claude"
is not a moving target across model version shifts (3.5 → 3.7 →
4 → 4.x all have materially different system-prompt bundles +
knowledge cutoffs + memory-retention language per archived Drive
artifacts).

Three-part scaffolding (v0):

1. tools/hygiene/capture-tick-snapshot.sh
   - Captures mechanically-accessible state:
     * Claude Code CLI version (`claude --version`)
     * CLAUDE.md + AGENTS.md + memory/MEMORY.md SHAs
     * Memory index byte count
     * Git HEAD + branch + repo
     * Date UTC
     * Per-user ~/.claude/CLAUDE.md SHA if present
   - Outputs YAML (default) or JSON (`--json`)
   - Agent fills model_snapshot + prompt_bundle_hash from
     session context (not CLI-accessible today)

2. docs/hygiene-history/session-snapshots.md
   - Session-level + significant-event pins (not per-tick)
   - Append-only row format: session_id / captured_utc /
     event (session-open | mid-session-pin | session-close |
     compaction) / agent / model / CLI version / git state /
     files SHAs / notes / prompt_bundle_hash
   - Seeded with one mid-session-pin for this tick's Otto-70
     capture (the session has been running ~70 ticks; actual
     session-open is earlier and unreachable for pins)

3. docs/hygiene-history/loop-tick-history.md schema extension
   - New "On snapshot pinning" subsection documenting the
     relationship: per-tick pins optional + inline in `notes`;
     session-level pins go in the sidecar file.
   - Snapshot capture is discipline, not gate — don't slow
     the autonomous-loop tick-close for every fire.

What the snapshot does NOT capture yet:

- model_snapshot — known to the agent from session context,
  not exposed by `claude --version` (which gives CLI version
  only). Agent fills.
- prompt_bundle_hash — no current tool reconstructs the
  system prompt bundle. Placeholder null until such a tool
  lands. Amara's Determinize-stage work potentially.
- Active permissions / skill set — session-specific; not
  captured in v0.

First run of the tool on this branch surfaced a separate
drift: memory/MEMORY.md is at 58842 bytes (~58KB, over the
FACTORY-HYGIENE row #11 24976-byte cap). Not fixed in this
PR — known-separately tracked drift.

Amara Stabilize-stage: 3/3 landed (with this PR).
  ✓ Action #3 — decision-proxy-evidence schema (PR Lucent-Financial-Group#222)
  ✓ Action #4 — branch-chat non-canonical framing (PR Lucent-Financial-Group#222)
  ✓ Action #2 — snapshot pinning scaffolding (this PR)

"Deterministic reconciliation" framing (Otto-67 endorsement):
snapshot pinning is the mechanism that reconciles "what Claude
knew" with "what Claude did" across time — essential for any
future audit, tuning, or Amara-style drift analysis.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 26, 2026
…sibling (Lucent-Financial-Group#147)

* Live-lock audit history: inaugural lesson integrated — prevention discipline for next time

Aaron 2026-04-23:

> if you want to beat ARC3 and do better than humans at uptime and
> other DORA metrics then your live-lock smell and the decisions you
> make to prevent live locks in the future based on pass lessons, the
> ability to integrate previous lessions and not forget is ging to be
> key.

Lesson-permanence is the factory's competitive differentiator.
Detection (audit script) is table stakes. Integration — recording the
lesson, consulting it forward, preventing re-occurrence — is the
product.

## What lands

- New "Lessons integrated" section in
  `docs/hygiene-history/live-lock-audit-history.md`
- Inaugural lesson from tonight's smell-firing event, structured as
  signature / mechanism / prevention with 4 concrete prevention
  decisions:
  1. External-priority stack is authoritative; agent reorders only
     internal priorities
  2. Live-lock audit at round-close is a gate-not-a-report
  3. Speculative-work permit requires external-ratio check first
  4. Tick-history rows are explicitly NOT external work; pair INTL
     with EXT when the smell is near firing
- Open carry-forward named: round-close-ladder wiring is a P1
  follow-up (BACKLOG row already filed earlier this session)

## Discipline

Every future smell firing files a lesson to this same section.
`memory/feedback_lesson_permanence_is_how_we_beat_arc3_and_dora_2026_04_23.md`
captures the full rule: detection is not enough, integration is the
product, lessons are consulted BEFORE taking actions that match known
failure-mode signatures, memory persists across sessions.

The pattern extends beyond live-lock: other detection mechanisms
(SignalQuality firing, Amara-oracle rejecting, drift-tick exceeding
threshold, OpenSpec Viktor failing rebuild-from-spec) should file
lessons to their respective hygiene-history files.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* samples: ServiceTitan factory-demo JSON API (v0, in-memory, stack-independent)

Minimal F# ASP.NET Core Web API serving CRM seed data as JSON. Any
frontend choice (Blazor / React / Vue / curl) consumes the same
endpoints. Ships now so the backend is not on the critical path when
Aaron picks the frontend stack.

## What lands

- `samples/ServiceTitanFactoryApi/ServiceTitanFactoryApi.fsproj`
  using `Microsoft.NET.Sdk.Web`; only explicit package ref is
  `FSharp.Core` (ASP.NET Core comes via framework reference, no
  Directory.Packages.props edit needed)
- `Seed.fs` — in-memory seed mirroring `ServiceTitanFactoryDemo/seed-data.sql`:
  20 customers, 30 opportunities (5 stages), 33 activities, 2 intentional
  email collisions. Deterministic fixed clock at 2026-04-23 00:00 UTC.
- `Program.fs` — minimal F# API with 9 endpoints: customers (list/detail),
  opportunities (list/detail), activities (list/per-customer), pipeline
  funnel (count + total-cents per stage), duplicates (customers sharing
  an email).
- `README.md` — framing (software-factory demo, not database pitch),
  endpoint table, design notes, v1 roadmap.

## Smoke-test output (verified)

```
GET /api/pipeline/funnel
[{"count":10,"stage":"Lead","totalCents":5400000},
 {"count":6, "stage":"Qualified","totalCents":4220000},
 {"count":6, "stage":"Proposal","totalCents":5720000},
 {"count":6, "stage":"Won","totalCents":2670000},
 {"count":2, "stage":"Lost","totalCents":490000}]

GET /api/pipeline/duplicates
[{"customerIds":[1,13],"email":"alice@acme.example"},
 {"customerIds":[5,19],"email":"bob@trades.example"}]
```

Build: 0 Warning(s), 0 Error(s). `dotnet run` starts the API;
curl confirms all endpoints respond correctly.

## Discipline signal

This is the third EXT commit of the session (CRM demo sample Lucent-Financial-Group#141,
CRM scenario tests in Lucent-Financial-Group#143, now this API). The live-lock audit's
inaugural lesson explicitly prescribed shipping external-priority
increments when the smell fires. Three landed this session, all on
priority #1 (ServiceTitan + UI) — the factory is correctly
response-pattern even before any of tonight's PRs merge to main.

## What this does NOT do

- Does NOT wire Postgres — in-memory only for v0; Npgsql wiring is
  a follow-up PR once Aaron confirms the DB driver
- Does NOT expose Zeta / DBSP / retraction-native language to the
  frontend — standard CRUD shape per the ServiceTitan positioning
  directive
- Does NOT implement writes — v0 is read-only; POST/PUT/DELETE is
  a follow-up
- Does NOT add auth — no authentication for v0
- Does NOT ship docker-compose — future PR bundles this API with
  Postgres in one command

Composes with:
- `samples/ServiceTitanFactoryDemo/` (SQL schema + seed) — sibling,
  same shapes; v1 wires this API to that schema
- `docs/plans/servicetitan-crm-ui-scope.md` — build sequence step 1
  (API skeleton) complete; step 2 (DB wiring) is next
- `memory/feedback_servicetitan_demo_sells_software_factory_not_zeta_database_2026_04_23.md`
- `memory/feedback_lesson_permanence_is_how_we_beat_arc3_and_dora_2026_04_23.md`

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* samples: ServiceTitan factory-demo C# companion API — parity with F# sibling

ServiceTitan uses C# for most of their backend with zero F#. Shipping
a C# companion to the F# API (Lucent-Financial-Group#146) so ST engineers evaluating the
factory see code in the language they already read fluently.
F# stays the reference — it's closer to math, theorems are easier to
express — but factory output matches audience stack.

## What lands

- `ServiceTitanFactoryApi.CSharp.csproj` — `Microsoft.NET.Sdk.Web`,
  nullable + implicit usings enabled, TreatWarningsAsErrors
- `Customer.cs`, `Opportunity.cs`, `Activity.cs` — records, one
  per file (MA0048)
- `Seed.cs` — deterministic in-memory seed, identical to F# Seed.fs:
  20 customers, 30 opportunities, 33 activities, 2 intentional
  email collisions
- `Program.cs` — 9 minimal-API endpoints, identical routes + JSON
  shapes to the F# sibling
- `README.md` — parity guarantee, design notes, C# specifics

## Smoke-test parity (verified)

```
GET /api/pipeline/funnel
[{"stage":"Lead","count":10,"totalCents":5400000}, ...5 stages]

GET /api/pipeline/duplicates
[{"email":"alice@acme.example","customerIds":[1,13]},
 {"email":"bob@trades.example","customerIds":[5,19]}]

GET /api/customers  -> 20 customers
```

Same seed, same shapes, same numbers as the F# version (Lucent-Financial-Group#146).
Frontends switch between them without code changes.

## Analyzer discipline passes

Build: 0 Warning(s), 0 Error(s) with the full SonarAnalyzer.CSharp +
Meziantou.Analyzer + Microsoft .NET Analyzers pack active. The C#
companion respects every rule the F# version's discipline
already encodes implicitly — StringComparer.Ordinal for GroupBy,
static-readonly for endpoint list, record-per-file, no-var-discarded.

## Discipline signal

Fourth EXT commit of the session (CRM demo Lucent-Financial-Group#141, CRM scenario tests
Lucent-Financial-Group#143, F# API Lucent-Financial-Group#146, now this C# API). All on Aaron's priority #1.
The live-lock audit's inaugural lesson prescribed "ship external-
priority increments when smell fires" — four landed in one session.

## Factory-pitch moment

This pair (F# + C# from the same spec, identical behaviour) is a
concrete factory-capability signal. The software factory produces
code in your stack, to your analyzer discipline, with parity across
languages. The pitch isn't "pick our language"; it's "your language,
enforced by our quality floor."

## What this does NOT do

- Does NOT rewrite or deprecate the F# sibling — both live
- Does NOT wire Postgres — same v0 scope
- Does NOT leak Zeta / DBSP / retraction-native concepts to the
  ST-facing surface
- Does NOT claim the C# version is the primary — F# is reference

Composes with:
- `samples/ServiceTitanFactoryApi/` (F# sibling)
- `memory/project_zeta_f_sharp_reference_c_sharp_and_rust_future_servicetitan_uses_csharp_2026_04_23.md`
- `memory/feedback_servicetitan_demo_sells_software_factory_not_zeta_database_2026_04_23.md`

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* rename: generic FactoryDemo.Api.CSharp (was ServiceTitanFactoryApi.CSharp)

Aaron 2026-04-23 directive:

> lets try to reduce the number of class and thing we call servce titan
> or this will be confusing in a Zeta repo. ... this is not a service
> titan repo, it's an open source repo.

Plus, 2026-04-23 follow-up on language priority:

> c# is a more popular language than f# so it makes sense to start
> with a factory c# demo anyways

## What renames

- `samples/ServiceTitanFactoryApi.CSharp/` →
  `samples/FactoryDemo.Api.CSharp/`
- Project name + csproj filename same rename
- `RootNamespace` `Zeta.Samples.ServiceTitanFactoryApi` →
  `Zeta.Samples.FactoryDemo.Api`
- `namespace` declarations in .cs files match
- Zeta.sln project entry updated
- README rewritten to generic framing (C# is the popular
  .NET language; demo starts there; F# stays reference)
- Root endpoint name field `"ServiceTitan factory-demo API (C#)"` →
  `"Factory-demo API (C#)"`
- All doc cross-references updated to new path names

Build: 0 Warning(s), 0 Error(s) with the full SonarAnalyzer +
Meziantou + Microsoft .NET Analyzers pack. Behaviour unchanged —
same 9 endpoints, same JSON shapes, same seed.

Memory rule:
`memory/feedback_open_source_repo_demos_stay_generic_not_company_specific_2026_04_23.md`
captures the positioning directive in durable form so future
agents don't re-introduce company-specific names.

Sibling renames land in separate PRs / branches:
- F# API sibling (currently PR Lucent-Financial-Group#146 / ServiceTitanFactoryApi)
- DB scaffold (PR Lucent-Financial-Group#145 / ServiceTitanFactoryDemo)
- CRM kernel sample (PR Lucent-Financial-Group#141 / ServiceTitanCrm)
- CRM-UI scope doc (PR Lucent-Financial-Group#144 / docs/plans/servicetitan-crm-ui-scope.md)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* FactoryDemo.Api.CSharp: smoke-test.sh — end-to-end endpoint + contract verification

I chose to land this because the JSON-shape parity claim we make
in the README ("byte-identical shapes between F# and C# versions")
needs a machine-verifiable check. A smoke test on the C# side is the
first half; the F# sibling gets the same pattern in a follow-up.

Starts the API on a random port, waits up to 10s for readiness,
then runs 19 checks against all 9 endpoints:

  - Root metadata: name, version, endpoints length
  - Collection lengths: customers (20), opportunities (30), activities (33)
  - Single-item lookup: customer #1 name, opportunity #1 stage
  - Per-customer activities: customer #1 has 4
  - Pipeline funnel counts per stage: Lead 10, Qualified 6, Won 6, Lost 2
  - Pipeline funnel totals in cents: Lead $54k, Won $26.7k
  - Duplicates: 2 pairs, (1,13) share alice@acme, (5,19) share bob@trades
  - 404 behaviour: missing customer returns 404

Shuts the API down cleanly on exit via trap + kill.

```
$ bash samples/FactoryDemo.Api.CSharp/smoke-test.sh
Building API...
Starting API on http://localhost:5235...

Factory-demo C# API smoke test
==============================
  OK   root.name contains 'Factory-demo'                  (true)
  OK   root.version                                       (0.0.1)
  OK   root.endpoints length                              (5)
  OK   /api/customers length                              (20)
  ...
  OK   missing customer HTTP status                       (404)

All checks passed.
```

dotnet, curl, jq — all standard dev tools. The demo does not ask
for anything exotic. Matches the FactoryDemo.Db smoke-test.sh
pattern on the sibling branch.

- Random high port (5100-5499) instead of fixed — reduces collision
  with other dev services.
- `curl -sf` for normal checks, `curl -o /dev/null -w "%{http_code}"`
  for the 404 case — the two paths have different error semantics so
  I use different tools for each.
- Shape-level assertions against numeric counts rather than raw JSON
  diff — makes the test tolerant of property-ordering differences
  between serializers. The parity claim is about *shape*, not byte-
  identity, so this matches intent.
- Trap + kill on EXIT — guarantees the API stops even on test
  failure or ctrl-C. No leaked background processes.

- Does NOT test the F# sibling. Same-pattern smoke-test for
  FactoryDemo.Api.FSharp lands in its branch (or a follow-up
  PR on that branch).
- Does NOT diff F# vs C# outputs directly. A cross-language
  parity-diff test composes better as a separate tool once both
  APIs have merged.
- Does NOT wire to Postgres. In-memory seed only; docker-compose
  + DB wiring is a separate PR.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* samples+audit: PR Lucent-Financial-Group#147 review-drain — sln BOM, signal-quality empty-case, audit fail-hard, endpoint lists

Drains 14 unresolved review threads on PR Lucent-Financial-Group#147 (FactoryDemo.Api.CSharp):
- Zeta.sln: strip leading blank line so 'Microsoft Visual Studio
  Solution File' is the first line (threads #2 #3).
- SignalQuality.fs: compressionRatio on empty input was 1.0, which
  composed as Quarantine via severityOfScore — flipped to 0.0 and
  added explicit empty-input Pass finding in compressionMeasure;
  also dropped unused System.Runtime.CompilerServices open
  (threads #4 #5).
- live-lock-audit.sh: fail hard (exit 2) when origin/main is not
  resolvable so a missing-remote CI checkout can't silently report
  'No commits found' -> healthy; switched --stat|awk file-list
  extraction to git diff-tree --name-only plumbing form
  (threads #1 #6).
- ServiceTitanFactoryApi README + Seed.fs: remove dead memory/
  and docs/plans/ links; replace Aaron's-name reference with
  'human maintainer' role wording; drop non-existent sibling
  SQL-seed refs (threads #7 #8 #9).
- FactoryDemo.Api.CSharp README + Program.cs + Seed.cs: fix dead
  refs to samples/FactoryDemo.Api.FSharp/ and samples/FactoryDemo.Db/
  to point at the real F# sibling samples/ServiceTitanFactoryApi/
  and to a BACKLOG row for the Postgres-backed follow-up
  (threads #11 #14).
- Program.cs + Program.fs: root endpoint index now advertises all
  9 routes including the parameterised {id} routes, matching the
  README tables (threads #12 #13).
- Thread #10 (project naming 'ServiceTitanFactoryApi.CSharp' in PR
  description): resolved in-thread — code/namespace already
  consistent (Zeta.Samples.FactoryDemo.Api); fix is PR-description-
  only, not code.

Build: dotnet build -c Release -> 0 Warning(s) 0 Error(s).

* drain PR Lucent-Financial-Group#147: post-rebase thread fixes — test-empty-ratio + smoke-endpoint-count

- tests/Tests.FSharp/Algebra/SignalQuality.Tests.fs: test asserted 1.0 for
  compressionRatio on empty input, but the fix in 16ad746 changed the
  convention to 0.0 (neutral = clean, not maximally suspicious). Updated
  the test expectation + name + comment to match the current code.
- samples/FactoryDemo.Api.CSharp/smoke-test.sh: root.endpoints length
  expectation was 5; Program.cs now advertises 8 routes in the index
  (post 16ad746 expansion). Corrected the smoke-test assertion.

Rebased onto origin/main (which advanced via Lucent-Financial-Group#146 FactoryDemo.Api.FSharp
merge); Zeta.sln conflicts resolved by keeping both FactoryDemo.Api.FSharp
and the ServiceTitanCrm/samples solution-folder additions.

Build gate: 0 Warning(s) / 0 Error(s) in Release.

* PR Lucent-Financial-Group#147 review-drain — Copilot pass on b4f5a49

Addresses five unresolved review threads:

- drop/README.md: sweep name attribution to "the human
  maintainer" role-ref (BP-name-attribution).
- samples/FactoryDemo.Api.CSharp/Program.cs: fix endpoint
  comment "9 concrete endpoints" → "8 API endpoints besides
  `/`" (array has 8; root excluded).
- samples/FactoryDemo.Api.CSharp/smoke-test.sh: per-run log
  via mktemp (collision-safe + non-/tmp-host-safe); print
  path on failure + success.
- samples/ServiceTitanFactoryApi/: delete stale F# sibling
  dir (PR Lucent-Financial-Group#146 already landed FactoryDemo.Api.FSharp on
  main with identical code); drop duplicate sln Project
  block + config duplicates; fix CSharp refs to point at
  the surviving FactoryDemo.Api.FSharp/.

Fifth thread (SignalQuality scope-creep) is judgment —
branch history is deep; splitting now adds more churn than
value. Replying with backlog-and-resolve per three-outcome.

* PR Lucent-Financial-Group#147 review-drain — 7 threads (Copilot + Codex)

Threads drained:
- btw.md: name attribution -> "human maintainer" / "the maintainer" (Copilot P1, AGENT-BEST-PRACTICES.md:284-292)
- live-lock-audit.sh: add --root to git diff-tree so root commit classifies correctly (Copilot P2)
- FactoryDemo.Api.CSharp Program.cs: add "/" to endpoints list for F# parity; bump smoke-test length 8->9 (Copilot P1 + Codex P2, same fix)
- FactoryDemo.Api.CSharp smoke-test.sh: reword mktemp comment to describe system temp dir accurately (Copilot P2)
- ServiceTitanCrm -> FactoryDemo.Crm: rename dir, fsproj, module namespace, RootNamespace, sln entry, test doc-comment; drop stale ServiceTitanFactoryApi bin+obj (Copilot P1, memory/feedback_open_source_repo_demos_stay_generic_not_company_specific_2026_04_23.md:59-66)
- SignalQuality.fs: compressionRatio + compressionMeasure short-circuit to 0.0 (Pass) below 64-byte threshold to avoid gzip-header-dominates Quarantine of legitimate short strings (Codex P1)

Drain log: docs/pr-preservation/147-drain-log.md preserves each thread verbatim (git-native high-signal preservation).

dotnet build -c Release: 0 Warning(s), 0 Error(s).

* PR Lucent-Financial-Group#147 review-drain second pass — 4 fix-inline + 3 scope-bleed

- Seed.cs + Seed.fs: rename contact 13 'Aaron Smith' -> 'Acme Contact
  (new lead)' (Copilot P2 name-attribution, parity preserved across
  C# / F# siblings).
- drop/README.md: correct 'only tracked file' wording to reflect the
  README.md + .gitignore two-sentinel design (Copilot P2).
- tools/audit/live-lock-audit.sh: docstring attribution 'Aaron's ...'
  -> 'Human-maintainer ...' (Copilot P1); add '-m' plus 'sort -u' to
  'git diff-tree' so merge commits bucket on their real files instead
  of mis-classifying as OTHR (Codex P1 — was skewing EXT/INTL/SPEC %
  and could disable the live-lock gate after a round of merges).
- docs/pr-preservation/147-drain-log.md: append second-pass per-thread
  audit trail (git-native preservation).

Three threads resolved as scope-bleed / already-addressed: operator-
input-quality-log.md (file not in PR diff, landed via 204bbb6 on
main), AUTONOMOUS-LOOP.md (file not in PR diff, zero Aaron on HEAD),
Tests.FSharp.fsproj (both SignalQuality + CrmScenarios already listed
at lines 26 and 49).

Build: 0W/0E. Audit sanity: live-lock-audit.sh still healthy with
merges now bucketed correctly.

* fix: markdownlint MD001/MD022/MD032 on Lucent-Financial-Group#147 drain-log (h3→h2 on Thread headers)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* drain: resolve 11 threads on Lucent-Financial-Group#147 (mix FIX + BACKLOG + Otto-256 reject)

Thread-by-thread outcomes across the 11 unresolved review threads on PR
Lucent-Financial-Group#147 (5 FIX, 2 BACKLOG, 2 Otto-256 REJECT, 2 already-addressed/stale):

FIXES (code):
- live-lock-audit.sh: replace `git show --stat` with explicit
  `git log -1 -m --first-parent --name-only` so merge commits classify
  against parent-1 only (the landing side). The prior `git show` form
  risked combined-diff semantics in some git versions; the explicit
  form is first-parent by construction (Codex P1).
- SignalQuality.fs: restore `compressionMinInputBytes = 64` threshold
  (dropped by the f1dc2bb merge-conflict resolution) and mark it
  `private` so it is not part of the public API surface (Copilot).
  Short-circuits `compressionRatio` + `compressionMeasure` to 0.0 for
  sub-threshold inputs, avoiding spurious Quarantine on short legitimate
  strings. Evidence reports UTF-8 byte count (consistent with the
  threshold's units) instead of `text.Length` chars (Copilot). Adjusted
  the empty-string test to assert the new 0.0 neutral value.
- smoke-test.sh: replace non-portable `mktemp -t <template>` with a
  pre-constructed absolute-path template rooted at `${TMPDIR:-/tmp}`
  where XXXXXX is the tail (BSD/macOS requires tail-XXXXXX; GNU accepts
  either). `.log` extension is appended via `mv` after creation so the
  single invocation is cross-platform (Copilot x2 — threads 4 + 10).
- CrmScenarios.Tests.fs: update doc-comment `samples/FactoryDemo.Crm`
  -> `samples/CrmSample` to match the canonical sample path on main
  (Copilot).

BACKLOG (deferred P2):
- Smoke-test deterministic port allocation (Codex P2) — replace
  RANDOM-in-range with OS-assigned ephemeral port via `--urls
  http://127.0.0.1:0` and log-line parse.
- FactoryDemo.Api.CSharp solution project-type GUID hygiene (Copilot)
  — align with modern SDK-style GUID used by other C# projects.

OTTO-256 REJECT (history-file exemption):
- docs/pr-preservation/147-drain-log.md (Copilot) and
  docs/hygiene-history/live-lock-audit-history.md (Copilot): both
  requested stripping first-name "Aaron" attributions. Declined per
  Otto-256 (2026-04-24) — history files exempt from the "no name
  attribution" rule; a P2 BACKLOG row already exists
  (`## P2 — FACTORY-HYGIENE — name-attribution policy clarification
  (history-file exemption)`) to codify this in AGENT-BEST-PRACTICES.md.

ALREADY-ADDRESSED (stale reviewer context):
- drop/README.md heading (Copilot): Copilot flagged "one tracked
  sentinel" but the current heading reads "two tracked sentinels"
  (fixed in a prior drain). Resolving as addressed.

Build: `dotnet build -c Release` -> 0 Warning(s), 0 Error(s).
Tests: `dotnet test --filter "FullyQualifiedName~SignalQuality"` ->
  22/22 pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 26, 2026
…e 3/5, L-effort design) (Lucent-Financial-Group#226)

* research: memory reconciliation algorithm — v0 design (Amara Determinize L-effort item)

Amara's 4th ferry (PR Lucent-Financial-Group#221 absorb) centerpiece proposal: replace
hand-maintained CURRENT-*.md distillations with generated views
over typed memory facts. Her sketch was ~40 lines of Python;
this is the design that downstream implementation follows.

~380 lines covering:

- MemoryFact record schema (id / subject / predicate / object /
  source_kind / source_path / source_anchor / timestamp_utc /
  supersedes / priority / status / confidence / tags)
- 6 schema invariants (at-most-one-active-per-canonical-key +
  monotone-timestamps-on-chain + retraction-leaves-trail + ...)
- Canonical-key normalization rules (7 apply; 3 deliberately
  NOT applied to preserve distinctions)
- Reconciliation pseudocode (group by canonical key, detect
  conflicts, follow supersession chains)
- Conflict output format → CONTRIBUTOR-CONFLICTS.md rows
- Rendering rules for CURRENT-<maintainer>.md + MEMORY.md
- 5-phase incremental migration (schema adoption → generator
  prototype → mechanical backfill → cutover → LLM extraction)
- CI integration hooks composing with rows #58, #59, #12
- Worked examples (MF-2026-04-23-001 "Aaron endorses
  deterministic reconciliation"; MF-2026-04-23-004 "Aaron
  grants full GitHub access")
- 5 open questions for Phase 1 PR design decisions

Composes with:

- Otto-73 retractability-by-design foundation — MemoryFact
  status (active / superseded / retracted) is the retraction-
  native primitive at the memory substrate
- PR Lucent-Financial-Group#222 decision-proxy-evidence — consulted_memory_ids
  can now reference MemoryFact.id directly
- PR Lucent-Financial-Group#225 memory-reference-existence CI (row #59) — generated
  output preserves the invariant by construction
- Zeta's ZSet algebra — MemoryFact records ARE Z-set entries
  at the memory layer; same primitive, different surface

Addresses MEMORY.md cap-drift (Otto-70 snapshot-tool
surfaced 58842 bytes vs. 24976-byte cap): a generated
index can be bounded by construction (top-N most-recent,
archive the rest).

Not implementation. Research doc only. Downstream arc:
schema adoption (S) → generator prototype off-CI (S-M) →
mechanical backfill (M) → cutover with retractability (M) →
LLM-assisted extraction (L research).

Amara Determinize-stage: 3/5 (with this PR).
  ✓ Live-state-before-policy (PR Lucent-Financial-Group#224)
  ✓ Memory reference-existence lint (PR Lucent-Financial-Group#225)
  ✓ Memory reconciliation algorithm design (this PR)
  Remaining:
  - Generated CURRENT-*.md views (L; this doc's Phase 2)
  - Memory duplicate-title lint enforcement (partial via
    AceHack PR #12; graduates via batch-sync)

Per Aaron Otto-73 retractability foundation: the design
itself embodies the thesis — supersession + status +
retraction make the memory layer's reconciliation
deterministic, same primitive as Zeta's data layer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* drain(Lucent-Financial-Group#226 P0+P1×2+P2×3 Codex): retraction semantics + cap consistency + smart-quote + pseudocode init + present-with-schema

Six substantive Codex findings on memory-reconciliation algorithm doc:

P0 (line 202) — retraction semantics inconsistency:
reconcile() filtered by status == 'active' which masked the
intent. Added explicit retraction-semantics docstring:
- Facts transition via explicit FactRetracted / FactSuperseded
  events; never deleted, only marked.
- reconcile() ignores retracted/superseded for liveness but
  STILL considers them when checking version-chain integrity.
- Updated chain check to operate over ALL facts in the group
  (including retracted/superseded), not just active ones —
  chain integrity needs the full history.

P1 (line 187) — stable fact identity vs grouping key:
Distinguished fact ID (stable identity, unique) from
(subject, predicate, canonical_key) grouping tuple (which
multiple facts can share under invariant-2's collision
case). Comment makes the distinction explicit.

P1 (line 270) — MEMORY.md cap inconsistency:
Default 30KB exceeded FACTORY-HYGIENE row #11 cap (24,976
bytes). Updated to 24,000 bytes — strictly under the hard
cap with ~1KB headroom for header/annotation overhead.

P2 (line 130) — smart-quote example ambiguous:
Both sides showed plain ASCII ('"' / "'"). Replaced with
explicit Unicode codepoint references (U+201C/D for
double, U+2018/9 for single) so the rule is unambiguous
in plain-ASCII source.

P2 (line 186) — pseudocode by_key[k] used before init:
Switched to defaultdict(list); added a comment noting the
equivalence to 'if k not in by_key: by_key[k] = []' for
non-Python implementers.

P2 (line 216) — CONTRIBUTOR-CONFLICTS.md 'empty' wording:
File is present and contains a schema; just unpopulated.
Updated text to 'present-with-schema-but-unpopulated; this
design starts populating it via the generator'.

* drain(Lucent-Financial-Group#226 P1+P2 Codex): chain-head liveness + chain-integrity for retired groups

P1 (line 210) — chain-HEAD liveness, not 'any active in group':
The reconcile filter marked a key live whenever any record
in the group had status==active. That's wrong — a key with
active(t=1) → retracted(t=2) has an earlier active record
but the HEAD of the supersession chain is retracted, so the
key is not live. Fix: `follow_supersession_to_head(group)`
walks supersedes-pointers to find the most-recent record;
liveness keyed on its status == active.

P2 (line 224) — chain integrity for fully retired groups:
The chain-integrity check looped over `accepted.items()`,
which only included keys with at least one active record.
Retired groups (all members retracted/superseded) could
have broken chains and we'd silently miss them. Fix: loop
over `by_key.items()` (all groups, including fully retired
ones). Chain integrity is independent of liveness.

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 28, 2026
… action item #2)

Amara 2026-04-23 decision-proxy + technical review (PR Lucent-Financial-Group#219 absorb)
action item #2: duplicate-link lint on memory/MEMORY.md. Observed
older state had duplicate entries ("Signal-in, signal-out" +
"Deletions > insertions" appearing twice each). Prevention-layer
for the discoverability defect: an index with duplicate entries
breaks the newest-first ordering invariant; fresh sessions can't
tell which entry is authoritative.

New artifacts:

- `tools/hygiene/audit-memory-index-duplicates.sh` — greps for
  `](foo.md)` link targets in the supplied MEMORY.md-shaped file,
  tallies, fails on any count > 1. Supports `--file PATH` for
  non-default targets, `--enforce` for CI exit-2 semantics.

- `.github/workflows/memory-index-duplicate-lint.yml` — runs the
  tool with `--enforce` on PRs touching `memory/MEMORY.md` or
  the tool itself. Safe-pattern compliant (SHA-pinned checkout,
  explicit minimum permissions, concurrency group, pinned
  runs-on, no user-authored context).

- FACTORY-HYGIENE row #60 documenting cadence / owner / scope /
  classification (prevention-bearing) + sibling link to row #58
  (memory-index-integrity — same-commit-pairing check).

Verification:

- actionlint clean on workflow
- Tool runs clean on in-repo memory/MEMORY.md (0 duplicates)
- Tool detects 1 duplicate on per-user MEMORY.md
  (project_learning_repo_khan_style_... appears twice) —
  confirms the class this lint prevents

First AceHack PR in this session was #11 (cost-parity audit).
This is PR #2 on AceHack per the Amara authority-axis split
(experimentation-frontier for new tooling; graduates to LFG via
batched consolidation when validated).

Row numbered 60 on AceHack to leave room for LFG's in-flight
row 58 (landed via PR Lucent-Financial-Group#220) and 57 (in-flight PR Lucent-Financial-Group#213) and
56 (in-flight PR Lucent-Financial-Group#204) to propagate here via future batch.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 28, 2026
…ion item #2) (#12)

* ci: memory-index duplicate-link lint + FACTORY-HYGIENE row #60 (Amara action item #2)

Amara 2026-04-23 decision-proxy + technical review (PR Lucent-Financial-Group#219 absorb)
action item #2: duplicate-link lint on memory/MEMORY.md. Observed
older state had duplicate entries ("Signal-in, signal-out" +
"Deletions > insertions" appearing twice each). Prevention-layer
for the discoverability defect: an index with duplicate entries
breaks the newest-first ordering invariant; fresh sessions can't
tell which entry is authoritative.

New artifacts:

- `tools/hygiene/audit-memory-index-duplicates.sh` — greps for
  `](foo.md)` link targets in the supplied MEMORY.md-shaped file,
  tallies, fails on any count > 1. Supports `--file PATH` for
  non-default targets, `--enforce` for CI exit-2 semantics.

- `.github/workflows/memory-index-duplicate-lint.yml` — runs the
  tool with `--enforce` on PRs touching `memory/MEMORY.md` or
  the tool itself. Safe-pattern compliant (SHA-pinned checkout,
  explicit minimum permissions, concurrency group, pinned
  runs-on, no user-authored context).

- FACTORY-HYGIENE row #60 documenting cadence / owner / scope /
  classification (prevention-bearing) + sibling link to row #58
  (memory-index-integrity — same-commit-pairing check).

Verification:

- actionlint clean on workflow
- Tool runs clean on in-repo memory/MEMORY.md (0 duplicates)
- Tool detects 1 duplicate on per-user MEMORY.md
  (project_learning_repo_khan_style_... appears twice) —
  confirms the class this lint prevents

First AceHack PR in this session was #11 (cost-parity audit).
This is PR #2 on AceHack per the Amara authority-axis split
(experimentation-frontier for new tooling; graduates to LFG via
batched consolidation when validated).

Row numbered 60 on AceHack to leave room for LFG's in-flight
row 58 (landed via PR Lucent-Financial-Group#220) and 57 (in-flight PR Lucent-Financial-Group#213) and
56 (in-flight PR Lucent-Financial-Group#204) to propagate here via future batch.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* memory(dedupe): drop 16 duplicate index rows (PR #12 lint dogfooding)

PR #12 introduces tools/hygiene/audit-memory-index-duplicates.sh
+ companion CI workflow. Running it on the current in-repo
memory/MEMORY.md found 16 duplicate index rows (14 distinct
target files; 2 with 3x duplication). Per Amara's 2026-04-23
discipline (decision-proxy + technical review action item #2):
keep the newest-first occurrence, remove older duplicates.

Eliminating these duplicates unblocks the PR's own lint —
dogfooding the discipline this PR introduces.

No content lost; the 16 rows removed all had a duplicate-newer
sibling preserved further up the index. Lint output now 'no
duplicate memory-index links in memory/MEMORY.md'.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene: fix audit-memory-index-duplicates.sh — P0 grep no-match guard + P2 path normalize + P1 scope comment

Three review-thread fixes from PR #12:

P0 (codex + Copilot, line 85): under `set -euo pipefail`, `grep -oE`
exits 1 when no link targets match, and `pipefail` propagates that
to the whole pipeline — the script aborted before reaching the
empty-result check. Wrapped grep in `{ ... || true; }` so the
no-match status is swallowed locally; the awk-empty branch then
correctly handles the no-duplicates case.

P2 (codex, line 84): `./feedback_x.md` and `feedback_x.md` are
semantically equivalent but tallied separately. Added a `sed
's|](\./|](|'` step after grep to strip the `./` prefix, so
equivalent forms collapse to a single key. Smoke-tested with a
fixture that has both forms — now correctly reports count=2.

P1 (Copilot, line 36): comment claimed "at the index level (outside
code blocks)" + "scoped to in-repo memory files" but the grep is a
plain line-grep that ignores fences and matches any `.md`. Aligned
the comment to what the code actually does, with explicit notes
about (a) why URL false-positives don't happen in practice (`.md`
suffix + URL char exclusion), (b) why fenced-code-block false-
positives don't happen on the intended target (MEMORY.md is a flat
link list — no fences), and (c) what callers should do if applying
to a target that does use fenced blocks (pre-strip).

Smoke tests:
  - memory/MEMORY.md → "no duplicates", exit 0 (regression check)
  - empty file → "no duplicates", exit 0 (P0 confirmation)
  - file with `./X.md` + `X.md` → count=2 reported (P2 confirmation)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 28, 2026
* research: cost-parity audit — Otto-65 real-billing addendum supersedes speculative figures

Human maintainer Otto-65 pasted actual GitHub billing UI for both
LFG org + AceHack personal. This commit appends a second-pass
"real billing data" section to the Otto-62 research doc
(AceHack/Zeta PR #11, already merged).

Key findings from the actual numbers:

LFG (Apr 2026 actuals):
- $43.71 gross metered, $66.62 discounts → $0 billed for Actions
- Copilot Business: $0.633/day × 1 seat = $19/mo (billed, not discounted)
- Top repo: Zeta at $41.72 of $43.71
- Confirmed monthly baseline: $27/mo = $8 Team + $19 Copilot (1 seat)

AceHack (Apr 2026 actuals):
- $50.45 gross, $51.21 discounts → $0 billed
- 1,773 of 3,000 included Actions minutes used (59%)
- Two "Zeta" entries in billing ($36.44 + $13.77) — human
  maintainer notes possible earlier-fork archaeology needed
- Monthly baseline: $4/mo GitHub Pro

Correction to Otto-61 claim: macOS multiplier cost

Otto-61 said macOS runs incur 10x multiplier cost "even on public
repos". Actual April 2026 billing shows macOS-3-core at $0.062/min
gross but $0 billed — fully covered by public-repo discount within
quota. The `gate.yml` macOS-on-AceHack-only split is still sound
cost-discipline for latency + quota-headroom reasons, but the
"10x-expensive-on-public-repos" framing was too strong. Corrected:
"10x gross but 0x billed on public repos within quota."

Personal Copilot clarified: ServiceTitan-sponsored seat (free
to human maintainer), separate from LFG's paid Copilot Business
seat. Personal premium-request usage: 84% of monthly allotment
(generalizes to the Otto-63 Frontier burn-rate UI directive).

Answer to "does AceHack get anything free that would limit LFG?":
No. Empirically confirmed — the two hosts have parallel,
independently-covered cost structures; neither subsidizes the other.

New BACKLOG candidate: archaeology on the "separate Zeta" in
AceHack billing ($13.77 gross/mo — may be a moribund fork to
archive or intentional active repo).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(markdownlint): MD032 list-bullet false-positive + MD022 wrapped heading on PR #14

- Line 312: rewrite "+ quota-headroom" -> "plus quota-headroom"
  (markdownlint saw `+` at line-start as one-item list MD032).
- Line 330-331: collapse two-line wrapped heading into single line
  (heading-on-line-N + content-on-line-N+1 fired MD022).

No semantic changes; pure lint debt cleanup so PR #14 can pass
gate (markdownlint).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* research(cost-parity): four PR #14 review threads — substantive errata + role-refs

Resolves all 4 unresolved review threads on PR #14 with substantive
corrections to the cost-parity audit document:

- (P2 cid 3134674765 line 248): added Errata note acknowledging
  the per-day samples sum to $43.88 vs declared monthly $43.71
  ($0.17 delta); preserved the per-day verbatim for traceability,
  named monthly as canonical, logged exact reconciliation as
  follow-up rather than blocking absorb.
- (P2 cid 3134674767 line 303): rewrote the "quota-based
  rationale" section to remove the contradiction. Public-repo
  unlimited discount and per-account included-minutes quota are
  TWO different mechanisms; original draft conflated them. New
  text names the public-repo discount as the relevant mechanism
  + flags policy-risk and fork-visibility-flip as the actual
  cost-flip triggers (not a quota threshold).
- (P1 cid 3142763716 line 314): renamed "### Aaron's personal
  Copilot" → "### Human maintainer's personal Copilot" per
  role-ref discipline. Two body-prose Aaron refs (lines 27,
  187) also reframed to "the human maintainer".
- (P2 cid 3142764383 line 297): corrected the macOS host-split
  claim. Original draft said gate.yml runs macOS only on
  AceHack — but the LFG per-day breakdown right above shows
  Apr 21 + Apr 22 had LFG macOS minutes (145 + 196). New text
  acknowledges the matrix runs on both forks + reframes the
  cost-discipline justification (latency + policy-risk
  headroom, not "matrix avoidance").

All four are substantive form-1 fixes per the
bulk-resolve-not-answer discipline (memory:
feedback_bulk_resolve_is_not_answer_recurring_pattern_aaron_2026_04_28.md).
No deferral notes; everything addressed in code.

* research(cost-parity): four NEW PR #14 review threads — propagate corrections + reconcile inconsistencies

Resolves the 4 new unresolved threads opened on commit 4662515:

- (P2 cid 3151505229 line 226): conditional billed-flip claim.
  Original text said "gross exposure > discount → billed" but
  the same section's Org budgets row says all products
  Stop-usage at $0 except GHAS/Copilot. Updated to clarify
  the as-written claim describes underlying GitHub billing
  semantic, while the actual operational behaviour is
  hard-stop via the budget rail.
- (P1 cid 3151505794 line 271): BACKLOG recommendation said
  "Document the LFG baseline $46/mo" but the addendum confirms
  ~$27/mo. Updated to $27/mo + cited Otto-62's correction
  ("i only used one user seat so only 19") that drops the
  Copilot Business line by ~$19.
- (P1 cid 3151505811 line 321): macOS-only-on-AceHack claim
  in TL;DR (line 17) and Actions-cost-awareness section (line
  66+) was wrong but only the inline correction (Otto-65
  addendum) said so. Now: (a) TL;DR points at the Otto-65
  correction directly; (b) Actions-cost-awareness section
  has an Errata-2026-04-28 block flagging the snapshot as
  stale + naming Otto-65 as canonical, with original
  preserved verbatim for traceability.
- (P1 cid 3151505818 line 390): "admin:org scope available"
  conflicted with status header "not yet applied" + with the
  addendum's data source (manual billing UI paste, not
  scope-elevated agent reads). Updated:
  - Status header now explicit that the addendum uses
    billing-UI screenshots, NOT scope-elevated reads.
  - BACKLOG row corrected to acknowledge the data source +
    name the still-pending scope elevation.

All four are form-1 substantive fixes per the
bulk-resolve-not-answer discipline. NO form-4 deferrals.

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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