Skip to content

feat: add autonomous_work spec for Development Harness (ADLC) - #190

Merged
sawka-harness merged 6 commits into
mainfrom
feat/autonomous-work-spec
Sep 4, 2026
Merged

feat: add autonomous_work spec for Development Harness (ADLC)#190
sawka-harness merged 6 commits into
mainfrom
feat/autonomous-work-spec

Conversation

@sunilgattupalle

@sunilgattupalle sunilgattupalle commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Expose the Harness Development Harness (ADLC) autonomous software-work API via the CLI as an opt-in plugin spec — not embedded in every binary, because ADLC is still in development (authn just shipped to qa0 in adlc-service #134; ST in #148 still open). Users install it only if they want it.

ADLC is the execution plane for autonomous AI-driven software work: WorkItems progress through plan→design→implement→review→merged, governed by WorkClasses, budgets, risk control, teams/members, triggers, and human gates.

What's added

plugins/autonomous_work.spec.yaml — 12 nouns, list/get/create/update/delete + execute variants:

  • work_item (list/get) + sub-resources via :variant + id_parts: work_item:timeline, work_item:budgets, work_item:phase (2-seg id), work_item:phase_artifacts (2-seg), work_item:artifact (3-seg)
  • work_item:resume, work_item:approve (execute; --decision approve|reject)
  • work_class, work_trigger, capability, risk_evaluator, team, member, member_template, software_component — full CRUD, YAML ask-bodies via --file
  • budget (list/get), budget:usage (get), budget:grant (execute)
  • content_source_connector (list/get) + content_source_connector:set_default (execute, PUT setDefaultConnectors)
  • agent_execution (execute — the autonomous-work trigger, POST /agent/executions)

Opt-in (not embedded)

The spec is not under pkg/spec/ (which is //go:embed'd into every binary). It lives at plugins/autonomous_work.spec.yaml. To use it, install it as a plugin spec:

mkdir -p ~/.harness/spec
cp plugins/autonomous_work.spec.yaml ~/.harness/spec/

The CLI auto-loads ~/.harness/spec/*.spec.yaml (specloader.LoadHomeSpecs); embedded specs always win on module-name collision. This is spec-only (no binary), so it doesn't use the binary-plugin install plugin <name> flow — a plain cp is the install. When ADLC is GA, promote this to pkg/spec/ (embedded) and drop the install step — the spec content is unchanged, only its location/gating changes.

This mirrors the companion MCP server toolset's optIn: true (harness/mcp-server#901), where HARNESS_TOOLSETS=+autonomous_work enables it.

Naming

Module/noun naming matches the companion MCP autonomous_work toolset: bare domain nouns (work_item, budget, team, …), disambiguated only on collision — work_trigger (not trigger, which clashes with the pipeline trigger noun).

Routing & auth (verified live against https://qa0.harness.io)

  • All routes project-scoped under /adlc/api/* on the standard gateway — no per-module base URL. The gateway rewrites /adlc/api/X → upstream /api/X.
  • Scope via orgIdentifier/projectIdentifier query params (templated {{auth.org}}/{{auth.project}}). Account via x-api-key/profile, not accountIdentifier query — paths start at /adlc/api/, never prefixed with {{auth.account}}/….
  • Auth: the active profile injects x-api-key: <PAT/SAT> automatically (pkg/client/client.go:287). PAT/SAT auth shipped to qa0 in adlc-service PR build(deps): bump helm.sh/helm/v3 from 3.21.3 to 3.21.4 #134 (ADLC-138).
  • x-internal routes (agent callbacks, Slack, demo seed) are deliberately excluded — service-to-service, not agent-callable.

Verification

  • go vet ./... ✅ clean
  • task build:main + cp bin/harness ~/.local/bin/harness
  • Before install: harness get noun work_itemnoun "work_item" not found (opt-in confirmed — not embedded)
  • After cp to ~/.harness/spec/: noun discovered; live against qa0:
    • harness --profile qa0 list work_item --org brett_org --project default → 24 items
    • harness --profile qa0 get work_item ADLC-18 → full fields
    • harness --profile qa0 list work_class → 3 classes
    • harness --profile qa0 get work_item:timeline ADLC-18 --json → timeline stages
    • harness --profile qa0 list team → 2 teams

Known follow-up

get work_item:timeline (and other :variants whose response shape differs from the parent noun) renders empty fields in table mode because the variant reuses the work_item noun's field set; --json returns the correct data. A follow-up could give each variant its own field projection.

Related

Expose ADLC's autonomous software-work API via the spec-driven CLI — one
declarative spec file, auto-embedded via //go:embed, no Go handler changes.

Nouns (bare domain nouns, matching the mcp-server autonomous_work toolset):
work_item, work_class, work_trigger, capability, risk_evaluator, budget,
team, member, member_template, software_component, content_source_connector,
agent_execution. Commands: list/get for work_item and its sub-resources
(timeline, budgets, phase, phase_artifacts, artifact), list/get/create/
update/delete for the work-config CRUD entities (YAML ask-bodies via --file),
and execute variants for the actions (work_item:resume, work_item:approve,
budget:grant, content_source_connector:set_default, agent_execution).

All routes project-scoped under /adlc/api/* on the standard gateway — no
per-module base URL. Scope via orgIdentifier/projectIdentifier query params
(account via x-api-key/profile, not accountIdentifier query). Paths use
{{auth.org}}/{{auth.project}} templating; sub-resources use id_parts (2/3)
for multi-segment ids. work_trigger (not trigger) to avoid clashing with
the pipeline trigger noun.

Excludes the x-internal routes (agent callbacks, Slack, demo seed) —
service-to-service, not agent-callable.

Auth: the active profile injects x-api-key (PAT/SAT) automatically
(pkg/client/client.go); PAT/SAT auth shipped to qa0 in adlc-service PR #134.

Verified: go vet clean, specloader tests pass, live against qa0
(harness list work_item -> 24 items; get work_item ADLC-18; list work_class;
get work_item:timeline; list team).

Design: adlc-service/docs/adlc-api-access/04-implementation-handoff.md
ADLC is still in development (authn just shipped to qa0 in adlc-service #134;
ST in #148 still open; the API is early). Exposing the spec embedded in every
CLI binary would surface an in-development API to all users before it's GA.

Move the spec out of the embedded pkg/spec/ set (which is //go:embed'd into
every build) to plugins/autonomous_work.spec.yaml. Users who want it install
it as a plugin spec:

    mkdir -p ~/.harness/spec
    cp plugins/autonomous_work.spec.yaml ~/.harness/spec/

The CLI auto-loads ~/.harness/spec/*.spec.yaml (specloader LoadHomeSpecs);
embedded specs always win on module-name collision. The spec is spec-only
(no binary), so it doesn't use the binary-plugin install flow
(`install plugin <name>`); a plain cp is the install.

When ADLC is GA, promote this to pkg/spec/ (embedded) and drop the install
step — the spec content is unchanged, only its location/gating changes.

Verified: go vet clean; before install `get noun work_item` -> not found;
after cp to ~/.harness/spec/ -> noun discovered + `list work_item` returns
24 items live against qa0.
@sawka-harness

Copy link
Copy Markdown
Collaborator

@sunilgattupalle this is great. i like this concept of an "opt-in" module. let me massage that concept a bit so it fits in with the install module or install plugin flow instead of forcing a manual copy.

Comment on lines +1115 to +1130
# ── agent_execution ─────────────────────────────────────────────────────────────

- command: execute agent_execution
verb: execute
noun: agent_execution
no_id: true
short: Launch an autonomous agent pipeline execution
handler_type: endpoint
endpoint:
method: POST
path: /adlc/api/agent/executions
query_params:
orgIdentifier: auth.org
projectIdentifier: auth.project
item_expr: it
columns: [execution_id, status]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

same as in the mcp PR, let's remove this endpoint

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

+1

@sawka-harness
sawka-harness merged commit 55901fa into main Sep 4, 2026
1 check passed
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.

4 participants