Commit Graph
21 Commits
Author SHA1 Message Date
mozempk 9fa9623b41 fix(conductor): ask design questions one at a time, not batched
Copilot CLI has no ask_user/elicitation tool for custom agents (confirmed
via docs: only execute/read/edit/search/agent/web/todo aliases exist).
The only way to get a live human reply is ending the agent's own turn
with plain text and waiting for the next user message. Conductor was
dumping every design question as one big numbered markdown block in a
single turn, which reads as a form, not a conversation.

Now conductor asks exactly one question per turn (plain text, numbered
candidate answers, one Recommended + Why, an Other: option, a Required
flag), ends its turn, waits for the real reply, then asks the next one.
Decisions are only persisted to decisions.md after the last question is
answered.
2026-09-10 02:51:01 +02:00
mozempk 245ad6b39f refactor(agents): hide architect and reviewer from /agent picker
Enforce single-entry-point: only conductor is user-invocable now.
architect and reviewer remain fully functional but are only reachable
as subagents that conductor delegates to internally, matching the
same internal-only treatment already given to scout/splitter/builder/
verifier/integrator/scribe.
2026-09-10 02:47:43 +02:00
mozempk 154e456d4c refactor(agents): remove interrogator, merge design Q&A into conductor
Confirmed via official Copilot CLI docs: there is no ask_user/elicitation
tool available to custom agents (only execute/read/edit/search/agent/web/
todo aliases exist). Subagent calls made through the 'agent' tool are
stateless — they run to completion and return one final result, with no
mechanism to pause mid-task for a live human reply.

This means conductor invoking interrogator via the agent tool could never
work: interrogator would run as a subagent regardless of whether conductor
itself was foreground or backgrounded, and subagents can't get real user
answers. That's why it was silently writing fabricated decisions.md/
questionnaire.md content instead of actually asking anything.

Fix: delete the interrogator agent entirely and fold its full Q&A
procedure directly into conductor's own DESIGN PHASE, run inline in
conductor's own foreground turn — never delegated. Updated the design
skill/prompt, AGENTS.md, README, QUICKSTART, and role-tier config to
match. Single entry point, no subagent path for anything that needs a
live human answer.
2026-09-10 02:40:07 +02:00
mozempk 099001728c fix(agents): document exact lh CLI flags in every agent profile
Every agent's PROCEDURE/OUTPUTS referenced lh subcommands vaguely (e.g.
'Run lh run event', 'lh memory get --shard failures'), forcing models to
guess flags at runtime instead of following the profile. Two real bugs
found this way:

- 'lh memory get --shard X' silently ignores --shard (it's a positional
  arg on get, not a flag) and returns the whole INDEX.md instead of the
  targeted shard. Fixed to 'lh memory get X' everywhere.
- lh run event/lane create calls had no required --type/--status/--id/
  --kind/--scope documented, so agents had to trial-and-error discover
  them. Added full, exact invocation syntax inline for every command
  each agent actually issues (run event, lane create, memory get/put,
  host --strategy, graph).
2026-09-10 02:33:22 +02:00
mozempk 34ce4eb5c5 fix(agents): correct user-invocable typo; document exact lh run flags
- All agent profiles used the misspelled 'user-invokable' property, which
  Copilot CLI silently ignores, so internal-only agents (scout, splitter,
  builder, verifier, integrator, scribe) were never actually hidden from
  the /agent picker. Renamed to the documented 'user-invocable'.
- conductor/architect instructions said only 'Run lh run event' with no
  flags, forcing the model to trial-and-error discover --type/--status/
  etc. Documented the exact lh run start/event/end CLI syntax inline.
2026-09-10 02:30:08 +02:00
mozempkandCopilot 981cbceecf fix(conductor): self-heal missing harness config via lh init --yes
conductor previously jumped straight to lh host, which succeeds even
without .agents/harness.config.json, then silently hit a hard failure
later reading .agents/memory/INDEX.md (lh doctor confirms: config not
initialised). New projects had no automatic recovery path — lh init
was documented as a manual step users had to remember.

- conductor now runs lh doctor first; if config is missing it runs
  lh init --yes (non-interactive defaults) and re-checks, before lh host
- still stops and reports the exact failing check if lh doctor finds
  something it can't self-heal (e.g. no verify commands configured)
- README/QUICKSTART updated: lh init/lh doctor documented as optional
  manual pre-flight, not a required step, since conductor self-heals

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-10 01:57:05 +02:00
mozempk cf13066baa feat(setup-npm-registry): browser-assisted classic PAT creation
When no token is found via --token/env/gh CLI, the script now opens
github.com/settings/tokens/new pre-scoped to read:packages with clear
instructions on Note/Expiration/Scopes, falling back to printing the
URL when a browser can't be launched (SSH, containers, CI). Add
--no-open to skip the launch attempt outright.

Also document the flow in README (new 'Generating a GitHub token'
section) and QUICKSTART troubleshooting, and add a hermetic test
covering the --no-open + piped-token path.
2026-09-10 01:44:28 +02:00
mozempk 66219525ba docs: fix wrong @agent mention syntax; @ only mentions files in Copilot CLI
Per official docs, agents are invoked via /agent, naming them in a prompt
("Use the conductor agent to..."), or --agent=NAME — never @name. Replaced
all @conductor-style examples. Also documented an observed limitation:
plugin-sourced agents are launchable (by name or --agent flag, both
verified live) but copilot's own 'plugins list' explicitly says custom-agent
introspection isn't finished yet, which likely explains why they aren't
proactively suggested/listed even though they work when named explicitly.
2026-09-10 01:37:47 +02:00
mozempk d74cb58821 docs: verify and clarify agent-namespacing vs skill-namespacing, add stale-session note 2026-09-10 01:34:26 +02:00
mozempk 5896213780 docs: clarify plugin agents are namespaced (redsen-lean-harness:conductor) outside this repo 2026-09-10 01:27:47 +02:00
mozempk 0e0e7d6bd4 fix: remove invalid $schema/extensions from plugin manifest; this was why the installed plugin exposed zero agents/skills
Root-caused live: declaring the agent-plugins.org $schema in plugin.json
opts Copilot CLI into Open Plugin Spec mode, under which the flat
agents/skills fields are silently ignored (0 loaded, no error). Combined
with the pre-existing nested extensions.com.github.copilot.* structure
(also not a real field), the installed plugin contributed zero agents and
zero skills to any consuming project — only this repo's own working copy
worked, because Copilot CLI separately auto-loads .github/agents and
.github/skills for the current git root regardless of any plugin.

Fix: drop $schema entirely, use flat top-level agents/skills/mcpServers
fields (matches the documented, non-spec plugin.json schema). Updated
validate.mjs to error on $schema/extensions instead of recommending them,
and to check the real agents/skills path fields.
2026-09-10 01:26:38 +02:00
mozempk 721b06cee7 fix: plugin.json uses invalid schema, breaking agent/skill discovery
plugin.json declared agents/skills under a nested extensions.com.github.copilot
object. The real Copilot CLI plugin schema uses flat top-level agents/skills/
mcpServers fields (verified against official docs). The nested form silently
loaded zero agents and zero skills for any consumer of the installed plugin,
which is why @conductor and /fast-track were unavailable outside this repo
even with the plugin installed and enabled.
2026-09-10 01:23:27 +02:00
mozempkandCopilot 58471c286f feat: zero-dependency npm registry setup script
scripts/setup-npm-registry.mjs configures npm to pull @redsentech
packages (e.g. @redsentech/lean-harness) from GitHub Packages:

- Discovers a token: --token flag > env (NPM_REGISTRY_TOKEN/
  GITHUB_TOKEN/GH_TOKEN) > `gh auth token` > interactive masked prompt
  (raw-mode stdin, no echo, no external deps).
- Verifies the token against the GitHub API, reports the authenticated
  login, and warns if the OAuth scopes are missing read:packages/
  write:packages.
- Writes/updates only its own two lines in .npmrc (scope registry +
  auth token), preserving every other line; idempotent on rerun.
- Never prints the full token (masked in all output).
- --dry-run, --unset (clean removal), --local, --scope, --registry,
  --skip-verify, --npmrc <path> flags.
- Confirms the result with `npm whoami --registry ...`.

Verified live end-to-end: real GitHub PAT via `gh auth token` ->
verified against api.github.com -> written to a scratch .npmrc ->
`npm whoami` succeeded. Also confirmed the scope-warning is accurate:
installing @redsentech/lean-harness with a token lacking read:packages
correctly 403s, exactly as the script warns it will.

Adds tests/setup-npm-registry.test.mjs (7 hermetic tests: dry-run,
write+preserve, token never printed, idempotent rerun, --unset,
custom scope/registry, clean failure with no token). Adds
"setup-npm-registry" npm script. Documents the script in README (The
`lh` CLI section) and docs/QUICKSTART.md (install + troubleshooting).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-10 00:56:30 +02:00
mozempkandCopilot 8330cf7900 ci: publish @redsentech/lean-harness to GitHub Packages
- Rename npm package scope @redsen -> @redsentech (GitHub Packages
  requires the scope to match the owning org/user login).
- Add publishConfig.registry pointing at npm.pkg.github.com.
- Add .github/workflows/publish.yml: on push of a vX.Y.Z tag (or manual
  dispatch), runs validate + test, checks the tag matches
  package.json's version, then npm publish using the auto-issued
  GITHUB_TOKEN (packages: write permission, no secret to manage).
- Update README/QUICKSTART lh-CLI install instructions for the private,
  org-scoped registry (.npmrc scope + auth token setup).
- Verified locally with npm publish --dry-run: 68 files, correct
  registry target, correct tarball contents.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-10 00:51:06 +02:00
mozempkandCopilot cadbec5797 docs: clarify manual vs automatic lh usage; lead with plugin install
- Add exhaustive table of every lh subcommand: who runs it automatically
  (agents, per their own instructions) vs what you run yourself (init,
  doctor, report).
- Reorder quickstart to lead with copilot plugin install (marketplace
  path, verified end-to-end on this machine), with onboarding script and
  clone+link as alternatives and explicit guidance on when to use each.
- Clarify the two-layer install model: plugin install only adds the
  behaviour layer; lh CLI (determinism layer) is a separate step until
  published to npm.
- README install section and troubleshooting table updated to match.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-10 00:46:17 +02:00
mozempkandCopilot 5ab8b59861 docs: add standalone quick start guide
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-10 00:11:30 +02:00
mozempkandCopilot 5ccf26f859 fix: tests depended on ambient CONTEXT7_API_KEY, broke in CI
\`lh doctor\`'s context7 check is a required, env-only check by design
(ADR: never inferred, never persisted). Tests that shell out to \`lh\`
or \`scripts/onboard.mjs\` inherited whatever CONTEXT7_API_KEY the
developer's shell happened to export, so \`doctor passes once the repo
is initialised\` and the onboard-script e2e test only ever passed on
machines with a real key set — never verified in a clean environment
until this CI run (no secret configured, correctly).

Fixed by injecting an obviously-fake fixture key (TEST_ENV in
helpers.mjs, exported and reused by onboard.test.mjs) into every
subprocess these tests spawn, so behaviour no longer depends on the
ambient shell. Verified locally with \`env -u CONTEXT7_API_KEY\` to
reproduce the CI environment exactly: 58/58 pass either way now.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-09 23:15:53 +02:00
mozempkandCopilot ce6b1563cd fix: npm test script fails with bare directory arg
\`node --test tests/\` throws MODULE_NOT_FOUND on this Node CLI (it
resolves the bare directory as a CommonJS entry module instead of a
test-runner glob) — this was masked locally all session because every
manual verification used \`node --test tests/*.test.mjs\` directly,
never the actual \`npm test\` script. CI caught it on the first real
run. Fixed package.json's test script to use the explicit glob.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-09 23:13:43 +02:00
mozempkandCopilot da20a6eaff feat: onboarding script, full lh flag reference, expanded README
- scripts/onboard.mjs: bootstraps a target repo onto the harness — copies
  the behaviour layer (.github/agents, skills, instructions, prompts,
  mcp.json, copilot-instructions.md, AGENTS.md), npm links the `lh` CLI,
  runs `lh init` + `lh doctor`, prints next steps. Idempotent: identical
  files are skipped, differing files require --force, re-running `lh init`
  on an initialized repo warns instead of failing. Supports --dry-run and
  --no-npm-link for CI/sandboxed use.
- tests/onboard.test.mjs: 5 new e2e tests (dry-run, full run, idempotent
  rerun, missing target dir, conflict + --force).
- README: new "Onboarding a new project" section, full lh flag reference
  for every subcommand (previously only one-line summaries), Development
  section mentions the onboarding script.

Live-tested against ~/Sources/ralph-runtime (a real, not-yet-git-tracked
project): git init, .github/ copied, `npm link` succeeded, `lh init`
ran, `lh doctor` correctly flagged its one real gap (no verify command
configured) rather than a false pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-09 22:58:46 +02:00
mozempkandCopilot cd36cc0efc fix: telemetry/memory flag mismatches, doc drift; add CI; self-dogfood
Parallel fleet audit (2 background agents) + direct work:

- src/commands/memory.mjs: `memory put --allow-secrets` was read as
  `flags.allowSecrets` (camelCase) but the CLI parser only emits
  kebab-case keys, so the flag was always undefined/false. Fixed to
  `flags['allow-secrets']`.
- Docs: `lh graph --brief` was referenced 14x across 5 agent.md files,
  harness.instructions.md, 4 SKILL.md files, onboard.prompt.md, and
  README, but `lh graph` has no --brief flag (terse output is already
  the default, --json/--severity are the only flags). Corrected every
  reference to match actual CLI surface.
- .github/workflows/ci.yml: run npm install/validate/test on node 20+22.
- Self-dogfooded `lh init --yes` in this repo, producing .agents/
  (harness.config.json, architecture.md, conventions.md, memory
  shards). `lh doctor` now reports all required checks green.
- Deduped .gitignore harness block against init's auto-managed block.

Verified: 53/53 tests pass, validate 0 errors, doctor all-green.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-09 22:50:07 +02:00
mozempkandCopilot 383129f571 feat: scaffold redsen-lean-harness v0.1.0
Recovered from crashed session (Node OOM). Repo contains full P0-P6
scaffold: plugin.json/marketplace.json, AGENTS.md, ADRs 0001-0006,
lh CLI (init/index/graph/lane/run/memory/host/report/doctor), 10
.github/agents, 12 CLI skills, instructions, context7 mcp.json, and
unit/e2e test suite.

Fixed: run.mjs read --in-tokens/--out-tokens but tests and CLI docs
use --input-tokens/--output-tokens, so telemetry totals were always 0.
Now accepts both forms.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-09 22:44:15 +02:00