1) Dual-numbering reconciliation
- ROADMAP groups Phase 1 by topic (1.1-1.8); PRH groups by execution
day (1.A-1.F). Added bidirectional mapping table to both docs so
agents can cross-reference any phase reference unambiguously.
2) Fresh-agent quick pointer at top of ROADMAP
- New section tells a new agent exactly which 4 docs to read, in
what order, and which task to pick up first (1.A from the tracker).
3) Broken sub-roadmap links neutralised
- 03_RICH_ITEMS_ROADMAP.md, 04_AGENT_API_ROADMAP.md,
05_INTAKE_ROADMAP.md were linked but did not exist. Replaced with
plain text + 'create when Phase N begins' note so the link doesn't
404. Matches the pattern already used in IMPLEMENTATION_TRACKER.
4) Runbook stubs created (Phase 1.F.11/1.F.12 placeholders)
- docs/runbooks/MEK_ROTATION.md — adapted from NoteLett bcad7d3
- docs/runbooks/SECRET_MANAGEMENT.md — secret inventory + resolution
path + compromise procedure + PII scrubbing rule
Each is a stub now; full content lands when Phase 1.F executes.
5) Stale 'today' wording removed from PRH baseline table
- Replaced 'after fix today' with 'as of 2026-05-25' so the doc
ages cleanly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves 5 related docs into docs/devops/gitea-runner/ to keep this
multi-doc workstream from colliding with future roadmaps and
delegation prompts in docs/devops/.
Renames:
HOSTINGER_GITEA_RUNNER_ROADMAP.md -> ROADMAP.md
HOSTINGER_GITEA_ACT_RUNNER_SETUP.md -> ACT_RUNNER_SETUP.md
GITEA_PACKAGES_PUBLISH_WORKFLOW.md -> PUBLISH_WORKFLOW.md
HOSTINGER_GITHUB_RUNNER_SETUP.md -> _PLAN_B_GITHUB_RUNNER.md
CODEX_DELEGATION_PROMPT.md -> (same name, moved)
All internal cross-links updated via sed sweep. Verified no stale
references remain.
Adds README.md in the new folder as the index + pattern doc for
future multi-doc workstreams (one-liner handoff, file map,
architecture summary).
Updated one-liner handoff path:
Read docs/devops/gitea-runner/CODEX_DELEGATION_PROMPT.md ...
Captures the exact bootstrap prompt to paste to Codex on the
Hostinger VM, plus a one-liner that just points Codex at the prompt
file (after Codex has the repo).
Also documents how to monitor Codex's progress from Cascade side
(grep roadmap-update commits) and how to recover if it gets stuck
(the checkbox state in the roadmap IS the resume pointer).
Adds HOSTINGER_GITEA_RUNNER_ROADMAP.md — a single execution tracker
that Codex on the Hostinger VM works through phase-by-phase, ticking
checkboxes and recording commit hashes as it goes.
Structure:
- 6 phases (P0 Pre-flight → P5 First real release) + P6 review handoff
- Each task: [ ] checkbox + Commit hash field + Status note
- Detail steps live in the two companion docs (act_runner setup +
publish workflow); the roadmap is the orchestrator
- Final report section Codex fills in when P0-P5 are complete
- Human review checklist (R1-R9) for verification after handoff
- Operating notes: commit message format, when to ask, never-do list
- Change log table Codex auto-appends to
Critical invariant repeated at P3.6 and P5.4: cross-Gitea SHA1
comparison must match. If it doesn't, Codex stops — it's the
load-bearing architectural guarantee that the dual-Gitea, no-sync-
script model rests on.
Also adds roadmap-pointer banners to the two companion docs
(HOSTINGER_GITEA_ACT_RUNNER_SETUP.md, GITEA_PACKAGES_PUBLISH_WORKFLOW.md)
so anyone landing there knows the master tracker exists.
Adds two new docs and a banner on the existing GitHub-runner doc.
WHY: the user already has Gitea Actions configured across all 20+
repos (.gitea/workflows/ci.yml). Building a parallel GitHub Actions
self-hosted runner pipeline is unnecessary work that also drags in
GitHub Organization migration pressure (with Vercel/Netlify pricing
side-effects on free tiers).
The canonical architecture instead:
- Each Gitea instance (corp Mac local + Hostinger VM) runs its own
act_runner.
- A single publish-packages.yml workflow lives in every package-
publishing repo.
- When the same git tag is pushed to both Giteas, each one builds
inside the same pinned Docker image (node:20-bookworm@sha256:...)
with the same lockfile, producing BYTE-IDENTICAL tarballs.
- No sync script is needed; the shared git tag IS the sync mechanism.
- Lockfile integrity hashes match across both registries, so corp Mac
and personal Mac + Hostinger prod all see the same packages.
New: HOSTINGER_GITEA_ACT_RUNNER_SETUP.md
- Codex-actionable prompt to install act_runner on the Hostinger VM
- Pre-flight checks (arch detection, Docker daemon, Gitea reachable)
- Idempotent user creation, SHA-verified binary download
- Docker mode runner config with labels mapping ubuntu-latest to
pinned Node image
- Smoke test + full E2E with throwaway @bytelyst/_runner-e2e-test
package
- The architectural invariant check: cross-Gitea SHA comparison —
same tag pushed to both must produce identical tarballs
- Monitoring (Gitea UI, API, systemd journal)
- Hardening, rollback, deliverables, guardrails, questions
New: GITEA_PACKAGES_PUBLISH_WORKFLOW.md
- The actual publish-packages.yml triggered by v* tags
- Docker image pinned by digest for build determinism
- pnpm@9.12.0 pinned, --frozen-lockfile, host-network container
- Token mounted as read-only secret file (not env var)
- Concurrency cancel-in-progress: false (never cancel a publish)
- Pack tarballs + SHA512 manifest as Gitea Release assets for audit
trail
- Two propagation strategies: reusable workflow (preferred) vs
sync-publish-workflow.sh script
- Operator runbook for cutting a release
- Failure-mode table + remediation
- Deliverables checklist
Updated: HOSTINGER_GITHUB_RUNNER_SETUP.md
- Added 'PLAN B' banner at the top
- Cross-links to the Gitea Actions docs
- Kept the doc intact as a valid alternative if priorities ever
shift to making GitHub Actions the publish driver
Adds the missing pieces revealed during review:
§1 Multi-repo registration decision — choose repo-level vs org-level
up-front. Default doc remains repo-level, but explicitly calls out
org-level as the scaling path for 20+ repos.
§2 Pre-flight check additions:
- Arch detection (x86_64 / aarch64) before downloading runner tarball
- github.com + objects.githubusercontent.com reachability check
- gh CLI auth status check (must be saravanakumardb1)
§4 Installation hardening:
- Step 1 is now idempotent (getent guards on useradd/usermod)
- Step 3 queries latest runner version via gh api (no more stale pin)
- Step 3 includes SHA256 verification of the downloaded tarball
against the release-notes manifest, with explicit STOP-if-mismatch
- Step 3 has REGISTRATION_URL var with commented Option A/B for
repo-level vs org-level scope
§5 Smoke test — added explicit git checkout/add/commit/push commands
for creating the runner/smoke branch (was implicit before).
§8 (renamed) — comprehensive org migration guide:
- Side-by-side table: personal account today vs under-an-org
- Bash loop to transfer all 18 repos via gh api
- git remote set-url commands for each local clone
- Post-migration org-level registration token fetch
- Workflow propagation strategies (reusable workflow vs sync script)
§9 (new) — Monitoring + observability:
- GitHub Actions tab per-repo + per-org workflow views
- Runner pool health (Settings → Actions → Runners) at repo + org level
- gh CLI commands for scripted monitoring (run watch, list, view, runners)
- Host-side journalctl + _diag/ inspection commands
§14 Questions — updated to ask about scope (repo vs org) first.
Section numbering shifted by +1 from §9 onward to make room for the
new Monitoring section.
Delegation prompt for the Codex agent running on the Hostinger VM to:
- Install a dedicated GitHub Actions self-hosted runner under gha-runner user
- Register it with saravanakumardb1/learning_ai_common_plat
- Run as a systemd service with auto-start
- Install Node 20 / pnpm 9 / gh CLI / Docker prerequisites
- Wire up local Gitea publish token
Includes full end-to-end validation that proves the actual publish
pipeline works:
- Creates a throwaway @bytelyst/_runner-e2e-test package
- Publishes to local Gitea
- Uploads tarball as GitHub Release asset
- Verifies Gitea registry returns the version
- Verifies pnpm install + require works from a clean directory
- Verifies the byte-identical-tarball invariant (sha256 match between
Gitea-served tarball and GitHub Release asset) — this is the key
guarantee that lockfiles will remain portable across corp Mac's
local Gitea after sync
- Documents cleanup of test artifacts
Plus pre-flight checks, hardening (systemd limits, log rotation,
workflow approval), scaling notes, deliverables checklist, guardrails,
rollback, and follow-up prompt list (publish-packages.yml,
bytelyst-sync script, SKILL doc).
Documents the local zsh chpwd hook + git credential helper that
auto-routes the gh CLI to the personal saravanakumardb1 account
whenever cwd is inside ~/code/mygh/, falling back to the keyring
active account elsewhere.
Captures the setup so it can be reproduced on a new laptop or by
another contributor with similar two-account needs. This is machine-
local config (lives in ~/.zshrc and ~/.gitconfig-personal), so it
intentionally lives in SKILLS/ rather than per-repo AGENTS.md.
Tail-end of the ts-any TODO-4 work uncovered a small class of false
positives the scanner still surfaced: ':any' that appears as TEXT inside
a string literal or JSX child, not as a TypeScript type annotation.
Examples:
const label = 'Energy: any'; // string content, not a type
<Badge>owner:any</Badge> // JSX text, not a type
Real TS ': any' annotations are followed by ',', ')', '=', ';', '>',
or end-of-line. Text occurrences are followed by alphanumeric / quote /
closing-tag delimiter characters \u2014 a clear distinguishing signal.
This commit adds a 10-line regex heuristic that skips occurrences where
':any' is followed by ' ', single quote, double quote, or '<'. The
companion AGENT_COMPLIANCE_ROADMAP.md entry for commit 79041714 already
listed this heuristic; the implementation just wasn't actually committed
at the time. This commit retroactively lands it so the working tree
matches the docs.
Verification: scripts/check-rule-violations.sh still emits 0 findings
across all 20 repos (no regression from the additional heuristic).
TODO-3 (commit 8ffe3616) added an optional 'logger' callback to MCPConfig
plus an exported McpLogger interface so consumers can route MCP output
to pino, Fastify request.log, structlog, etc., instead of the default
global console. The package had zero unit tests; the new interface
relied on type-system validation alone.
This commit adds packages/mcp-client/src/logger.test.ts (4 tests) to
cover the public contract introduced by TODO-3:
1. defaults to global console when no logger is provided
\u2014 verifies the '?? console' fallback in the constructor.
2. injected logger receives no spurious calls on early-return paths
\u2014 disconnect() when not connected is a no-op; logger must
not be invoked.
3. structural-typing acceptance test \u2014 a pino-shaped logger
(no-op methods) must construct cleanly. Guards the McpLogger
interface from accidental narrowing during future refactors.
4. variadic-args contract \u2014 McpLogger.info('msg', {ctx}, 42)
accepts trailing structured args; matches console + pino + Fastify.
The deeper integration paths (connect / callTool / readResource) spawn
StdioClientTransport subprocesses and aren't safely runnable in a unit
context; they're covered indirectly by consumers (admin-dashboard
uses the same client and has integration tests).
Result: mcp-client moves from 0 tests to 4 tests passing.
The DevOps admin preHandler read 'auth' as '(request as any).auth'.
The proper Fastify pattern is 'declare module' augmentation in
@bytelyst/fastify-auth, but the inline cast through 'unknown' is
sufficient for now and avoids touching the shared auth package.
Changed:
- 'const auth = (request as any).auth;' \u2192
'const auth = (request as unknown as { auth?: { role?: string } }).auth;'
Inline comment notes the cleaner 'declare module' alternative.
Final ecosystem state:
scripts/check-rule-violations.sh: 0 findings across all rules \u2713
web-hardcoded-hex: 0 \u2713
b5-hardcoded-product-id: 0 \u2713
b4-console-log: 0 \u2713
b4-swift-print: 0 \u2713
b4-python-print: 0 \u2713
ts-any-type: 0 \u2713
b7-emoji-in-code: 0 \u2713
Per user request: 'use the local Gitea and make sure all packages
in Gitea are up to date'.
Built all packages from learning_ai_common_plat/packages/* and ran
scripts/gitea/publish-outdated-packages.sh against the local Gitea
npm registry (http://localhost:3300/api/packages/bytelyst/npm/).
Manifest-based hash comparison flagged 4 packages whose built dist/
content has changed since the last published tarball:
@bytelyst/auth-ui 0.1.5 → 0.1.6
@bytelyst/config 0.1.7 → 0.1.8
@bytelyst/dashboard-shell 0.1.5 → 0.1.6
@bytelyst/mcp-client 0.1.0 → 0.1.1
All four bumped + published successfully. Remaining 60 packages
verified up-to-date. One package skipped by design:
@bytelyst/react-native-platform-sdk (RN — not in npm publish set)
Also incidentally fixed an mcp-client build break before this run:
stale dist/ + node_modules/.cache made tsc think MCPClient was
missing a 'log' property, even though the source had been correctly
refactored to use a private 'log: McpLogger' field. A clean
'rm -rf dist node_modules/.cache && pnpm build' resolved it; no
source changes needed.
Files updated:
- packages/auth-ui/package.json
- packages/config/package.json
- packages/dashboard-shell/package.json
- packages/mcp-client/package.json
- scripts/gitea/.publish-manifest.json (new content hashes)
After this commit, every published @bytelyst/* tarball in local
Gitea matches the source tree exactly.