Business needs as a checkable spec: needs.yaml + question_lint pass
Test / test (push) Successful in 27s
Test / test (push) Successful in 27s
A content repo may now state what the business needs the site to do,
apart from how the pages word it. question_lint checks each need
against the pages and aggregates.yaml:
- a path of submissions gets the answer into `lands_in`, within
`max_steps` and a required-field budget (`max_fields`);
- `handled_by` holds a desk over that bucket;
- every `done_when` state is reachable through the moves that desk
(or a self_transition) offers, and no record strands on the way;
- a disabled alternative is named as the reason when it is one;
- `planned: true` reports the gap as a warning instead of failing.
Personas - visitors in their own words - become typed `choice` tasks
(the page's question, its alternatives as the options) written as
JSONL by `--needs-tasks` (`--skim`: headings only). Any external
answering engine returns `{id, choice, confidence}` lines, graded by
`--needs-score [--min-accuracy]`: a misroute is a wording defect. The
engine stays outside this crate on purpose so classifiers and LLMs
can be compared on the same tasks. The runtime never reads the file.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4jrCgLiKKHAEFuZUJjckH
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
75000421ae
commit
188f9bf574
@@ -719,6 +719,20 @@ pub fn validate_relay_url(relay: &str) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Fetches `needs.yaml` from the content repo root - the business's
|
||||
/// needs spec `question_lint` checks the pages against (see
|
||||
/// `crate::needs`). Optional: a fetch failure means the repo declares
|
||||
/// none. The runtime never reads it.
|
||||
#[cfg(feature = "ssr")]
|
||||
pub async fn load_needs_from_gitea(repo_url: &str, branch: &str) -> anyhow::Result<Option<String>> {
|
||||
let (owner, repo) = parse_owner_repo(repo_url)?;
|
||||
let api_base = gitea_api_base(repo_url)?;
|
||||
let client = openidconnect::reqwest::Client::new();
|
||||
Ok(fetch_gitea_file(&client, &api_base, &owner, &repo, branch, "needs.yaml")
|
||||
.await
|
||||
.ok())
|
||||
}
|
||||
|
||||
/// Fetches and parses `site.yaml` from the content repo root. A fetch
|
||||
/// failure (typically 404 - the file is optional) yields the default
|
||||
/// config; a file that exists but doesn't parse or validate is a real
|
||||
|
||||
Reference in New Issue
Block a user